本文主要是介绍一、Spring基础 --- 基础内容(一) (咕P4),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、Spring简介
1 来源
Struts与Hibernate可以做什么事?
Struts:Mvc中控制层解决方案 可以进行请求数据自动封装、类型转换、文件上传、效验…Hibernate:持久层的解决方案; 可以做到,把对象保存到数据库, 从数据库中取出的是对象。
传统的开发模式、开发流程
传统的开发模式:基于mvc模式进行项目开发
基于mvc的项目框架结构:Entity / dao / service / action// 1. 实体类class User{}//2. daoclass UserDao{.. 访问db} //3. serviceclass UserService{UserDao userDao = new UserDao();}//4. actionclass UserAction{UserService userService = new UserService();..拿到数据或结果}用户访问:/user.action ----> Tomcat (服务器创建Action、Service、dao
思考
思考:1. 对象创建创建能否写死?2. 对象创建细节对象数量action 多个 【维护成员变量】service 一个 【不需要维护公共变量】dao 一个 【不需要维护公共变量】创建时间action 访问时候创建service 启动时候创建dao 启动时候创建3. 对象的依赖关系action 依赖 serviceservice依赖 dao=======================================================总结:spring就是解决上面的问题的!简单来说,就是处理对象的创建的、以及对象的依赖关系!
2 spring概念
官网地址 :http://www.spring.io
1.1 作用
作用:简化Java开发的。Spring不仅只是一个框架,Spring已经成为了一种生态。(与其说是Java开发,不如说是Spring开发)Spring可以做非常多的事情,但归根结底,支撑Sprine的仅仅是少许的基本理念,所有的理念都可以追溯到Sprine最根本的使命上!简化java开发。这是一个郑重的承诺。许多框架都声称在某些方面做了简化,但Spring的目标是致力于全方位的简化java开发。这势必引出更多的解释,Spring是如何简化Java开发的?为了降低Java开发的复杂性,Spring采取了以下4种关键策略:1、基于POI0的轻量级和最小侵入式编程;2、通过控制反转和依赖注入以及面向接口实现松耦合;3、基于切面和惯例进行声明式编程:4、通过切面和模板减少样板式代码,
1.2 历史来源
EJB历史:一个java应用层程序,是由许多个类组成的,这些类之间必然存在依赖关系,当项目越来越大,依赖关系越来越复杂,需要一个专业的框架来处理类之间的依赖关系,为了解决这个问题,SUN公司推出了EJB(重量级)专门用来解决类的依赖问题。Spring历史:Spring (Spring Framework)是一个开源框架,最早由Rod johnson创建,并在《Expert One-on-One:.J2EE Design andDevelopment》这本著作中进行了介绍。解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。但Spring不仅仅局限于服务器端开发,任何java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。
1.3 Spring专有名词
+++ 组件/框架设计1)侵入式设计引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。例如: Struts框架(使用struts的校验功能,必须继承ActionSupport,这是一种侵入式设计)2)非侵入式设计引入了框架,对现有的类结构没有影响。例如:Hibernate框架 / Spring框架3)区别侵入式、非侵入式的要点是:引入该框架是否要继承某个特定类。如:引入struts框架,如果要实现校验功能,action必须要继承ActionSupport,这是侵入式设计,所以struts是侵入式框架。引入hibernate,虽然配置了xml配置文件,但是dao无须继承什么类。所以hibernate是非侵入式设计。
+++ 控制反转(IOC)和依赖注入(DI)1) Inversion on Control , 控制反转 IOC对象的创建交给外部容器完成,这个就做控制反转.2) dependency injection 处理对象的依赖关系区别:控制反转, 解决对象创建的问题 【对象创建交给别人】依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】先有控制反转,再有依赖注入,(一个流程步骤)
+++ AOP面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。切面举例:事务、日志、权限;
+++ bean的各种名称:虽然Spring用bean或者javaBean来表示应用组件,但并不意味着Spring组件必须要遵循JavaBean规范。一个Spring组件可以是任何形式的POJO(POJO (Plain Ordinaryjava Obiect)简单的java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称)。
3 spring-frameworek框架
3.1 地位
spring framework是整个spring中最核心的一个部分。其他项目均是基于该项目进行开发或拓展的。
3.2 核心模块
3.2 结构图
1、spring-framework是一个工程(框架),里面有许多模块。每一个模块对应一个jar。比如beans、context等。2、没有【spring-all】这个jar。如果想使用,则必须一个一个引入。3、spring核心模块:core、beans、context、sprl。4、如果想使用spring,则必须引入这四个核心jar(core、beans、context、spel,有的版本还需引入日志jar)。
各个模块之间的依赖关系图
4 环境准备
4.1 spring-framework版本号说明
spring下载时
版本说明
4.2 jar包下载
官网下载教程https://blog.csdn.net/m0_52861000/article/details/128883819jar包下载地址(注意:没找到release库,只找到了SNAPSHOT库):https://repo.spring.io/ui/native/snapshot/org/springframework/spring/
下载jar包说明: 1、spring framework框架是一个工程,里面有许多模块,如core、beans、context等。2、spring各个版本中:1)在3.0以下的版本,源码有spring中相关的所有包【spring功能 + 依赖包】,如2.5版本;2)在3.0以上的版本,源码中只有spring的核心功能包【没有依赖包】(如果要用依赖包,需要单独下载!)3、下载spring framework框架时候,实质上是一个zip压缩包。压缩包里面有zip、api文档、文档约束。而zip中有该spring版本对应的模块(core、beans、context等jar)。【不存在一个包含所有模块的jar】3、maven依赖引入spring framework框架时,没有spring-all坐标,只有具体的模块的坐标。所以只能一个模块一个模块的引入。
1、不存在一个包含所有模块的jar
2、下载讲解
spring 库
4.3 基础案例
引入jar文件
1) 源码, jar文件:spring-framework-3.2.5.RELEASEcommons-logging-1.1.3.jar 日志spring-beans-3.2.5.RELEASE.jar bean节点spring-context-3.2.5.RELEASE.jar spring上下文节点spring-core-3.2.5.RELEASE.jar spring核心功能spring-expression-3.2.5.RELEASE.jar spring表达式相关表以上是必须引入的5个jar文件,在项目中可以用户库管理!
在org/jsoft/demo引入applicationContext.xml(或bean.xml)配置文件
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><bean id="user" class="org.jsoft.a_hello.User"></bean></beans>
创建实体
public class User {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
测试
public class App {@Testpublic void testIOC() {//加载配置文件,创建Bean工程Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);//获取对象User u=(User) factory.getBean("user");System.out.println(u.getAge());}@Testpublic void testIOC2() {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");//获取对象User u=(User) ac.getBean("user");System.out.println(u.getAge());}
}
5 spring注解驱动发展
6 IOC、DI
IOC控制反转:本质上就是将程序中原本手动创建的对象,交给spring容器去处理。
【举例:我吃包子,需要买面、油等,然后手动做。但是我如果直接去包子铺买,就省去很多事情。spring容器就是包子铺(Spring Ioc就是包子铺,对象就是包子。)】
二、基于XML配置方式的实现
1 基础环境搭建
1)新建java项目
2)导入相关的jar包
创建bin文件夹,然后复制spring框架中的lib核心包(core、beans、context、spel)
将bin文件夹设置为library库
3)创建spring配置文件
在src目录下创建applicationContext.xml配置文件
注意:通过该方法创建配置文件,必须使用idea的正式版本,idea的社区版本不能之间创建xml。
applicationContext.xml 文件内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>
4)创建对应的java类
package com.hlp.spring.ioc.beans;public class Car {private String name;private String id;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}
}
5)配置文件中注册bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 通过bean标签将car实例创建--><bean class="com.hlp.spring.ioc.beans.Car"></bean></beans>
6)java代码实现
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = ac.getBean(Car.class);System.out.println(car);}
}
注意第一次启动抛 ClassNotFoundException异常,因为缺少logging依赖,导入即可
2 IOC容器
2.1 基于XML创建IOC容器
1)方式一: BeanFactory
方式一:Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);
@Testpublic void testIOC() {//加载配置文件,创建Bean工程Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);//获取对象User u=(User) factory.getBean("user");System.out.println(u.getAge());}
2)方式二: ApplicationContext
ClassPathXmlApplicationContext作用:加载classpath根目录下的配置文件,创建IOC容器。1、加载一个配置文件。然后创建IOC容器。加载classpeth根类路径下ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");加载指定类路径下ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");2、加载多个配置文件。然后创建IOC容器。ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml","app2.xml");
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = ac.getBean(Car.class);System.out.println(car);}}
2.2 BeanFactory和ApplicationContext的区别
ApplicationContext、BeanFactory都是IOC容器。ApplicationContext是BeanFactory的子接口。ApplicationContext功能肯定比BeanFactory的功能更强大。ApplicationContext容器在初始化的时候,就会初始化Bean。而BeanFactory容器中的Bean是懒加载,在初始化的时候,不会初始化Bean,只有在调用getBean时,才会创建对象。
2.3 容器相关方法
1)一般方法
public static void main(String[] args) {//1.创建IOC容器ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/g_transaction_detail/applicationContext.xml");//2.根据名称获取bean对象DeptDao deptDao=(DeptDao) ac.getBean("deptDao"); //强制转换DeptDao deptDao2 = ac.getBean("deptDao", DeptDao.class);//利用了泛型,无需转换//3.根据类型获取bean对象(该类型只能在容器中有唯一的对象,否则报错)DeptDao deptDao3 = ac.getBean(DeptDao.class);//4.获取容器中bean对象的个数int num = ac.getBeanDefinitionCount();//5.获取容器中所有bean的名字String[] beanDefinitionNames = ac.getBeanDefinitionNames();}
2)getBeans( ) 方法
根据name获取
<bean class="com.hlp.spring.ioc.beans.Car" name="myCar"></bean>
public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
根据id获取
<bean class="com.hlp.spring.ioc.beans.Car" name="myCar" id="myCar2"></bean>
public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
根据class文件获取
<bean class="com.hlp.spring.ioc.beans.Car" ></bean>
public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean(Car.class);System.out.println(car);}
如果我们根据类型去容器中获取对象,如果该类型在容器中有多个实例,那么会抛出异常信息
这时,我们可以根据组合的方式去查找
组合方式查找
<bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean><bean class="com.hlp.spring.ioc.beans.Car" ></bean>
public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car",Car.class);System.out.println(car);}
3 Bean的实例化
SpringIOC容器,是spring核心内容。作用: 创建对象 & 处理对象的依赖关系
IOC容器创建对象, 有几种方式:1) 调用无参数构造器2) 带参数构造器3) 工厂创建对象工厂类,静态方法创建对象工厂类,非静态方法创建对象
3.1 Bean标签
<bean>:用于配置对象,让spring来创建。默认情况下调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。class:指定类的全限定类名,用于反射创建对象,默认情况下调用无参构造函数。如果不进行配置并且类中没有无参构造方法,则会创建失败。id:给对象在容器中提供一个唯一标识,用于获取对象。name: 设置别名,在BeanFactory的getBean(“name”)中可以获取相应的bean。scope:指定对象的作用范围singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象prototype:多例的,调用getbean方法时候创建request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 sessioninit-method:指定类中的初始化方法名称destroy-method:指定类中销毁方法名称autowire:自动装配属性byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入default:默认值,不自动装配
3.2 Bean的实例化
3.2.1 构造函数
1、使用无参构造创建对象(实例对象必须有无参构造)<bean class="com.hlp.demo02.User" id="user"></bean>2、使用有参构造创建对象(实例对象必须有有参构造)<bean class="com.hlp.demo02.User" id="user"><constructor-arg name="name" value="张三"></constructor-arg><constructor-arg name="age" value="123"></constructor-arg></bean>
3.2.2 自定义工厂实例化
1)静态工厂创建对象
通过工厂类的静态方法获取对应的实例对象
MyBeanFactory静态工厂
public class MyBeanFactory {public static Car getInstance1(){return new Car();}
}
applicationContext-static.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 静态工厂配置--><bean class="com.hlp.spring.ioc.MyBeanFactory" factory-method="getInstance1" id="myFactory"></bean>
</beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");Car car = (Car)ac.getBean("myFactory");System.out.println(car);}
}
2)动态工厂创建对象
通过工厂类的方法获取对应的实例对象
MyBeanFactory工厂
public class MyBeanFactory {public Car getInstance1(){return new Car();}
}
applicationContext-static.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 注册动态工厂--><bean class="com.hlp.spring.ioc.MyBeanFactory" id="myFactory"></bean><!-- 从工厂中获取car对象--><bean factory-bean="myFactory" factory-method="getInstance1" id="xxxx"></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");Car car = (Car)ac.getBean("xxxx");System.out.println(car);}
}
3.2.3 FactoryBean工厂实例化
1)FactoryBean介绍
1、FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。2、Spring为什么使用FactoryBean一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring 为此提供了一个 org.Springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 bean 的逻辑。3、FactoryBean允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。同时,Spring框架还提供了一些内置的FactoryBean实现,例如ProxyFactoryBean和JndiObjectFactoryBean,可以帮助我们更方便地创建一些常见的Bean实例。
2)FactoryBean接口
1、getObject()方法:获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。2、getObjectType()方法获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。3、isSingleton()方法判断由此工厂创建的对象实例是否为单例模式。默认情况下,FactoryBean创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。4、FactoryBean在Spring中的作用当配置文件中< bean>的 class 属性配置的实现类是 FactoryBean 时,通过 getBean()方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象。相当于FactoryBean#getObject()代理了 getBean()方法。
public interface FactoryBean<T> {// 获取由此工厂创建的对象实例T getObject() throws Exception;// 获取由此工厂创建的对象实例的类型Class<?> getObjectType();// 判断由此工厂创建的对象实例是否为单例模式default boolean isSingleton() {return true;}
}
3)FactoryBean使用
User.java
public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}...}
UserFactoryBean .java
public class UserFactoryBean implements FactoryBean<User> {public User getObject() throws Exception {User user=new User("张三",12);return user;}public Class<?> getObjectType() {return User.class;}public boolean isSingleton() {return false;}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.UserFactoryBean" id="factoryBean"></bean></beans>
App.java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("factoryBean",User.class);System.out.println(user.getName());System.out.println(user.getAge());}
}
4)FactoryBean使用场景
1、动态创建对象
public class MyFactoryBean implements FactoryBean<Object> {@Overridepublic Object getObject() throws Exception {// 根据配置或条件动态创建对象if (someCondition) {return new MyObject();} else {return new AnotherObject();}}@Overridepublic Class<?> getObjectType() {// 返回实际创建的对象的类型return Object.class;}@Overridepublic boolean isSingleton() {// 返回是否为单例对象return true;}
}
2、对象的装配和初始化
public class MyFactoryBean implements FactoryBean<MyObject> {private String name;private int age;@Overridepublic MyObject getObject() throws Exception {// 创建对象并进行装配和初始化MyObject myObject = new MyObject();myObject.setName(name);myObject.setAge(age);return myObject;}@Overridepublic Class<?> getObjectType() {return MyObject.class;}@Overridepublic boolean isSingleton() {return true;}// 设置属性值的方法public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}
3、对象的代理和包装
public class MyFactoryBean implements FactoryBean<MyObject> {private MyObject target;@Overridepublic MyObject getObject() throws Exception {// 对目标对象进行代理和包装MyObjectProxy proxy = new MyObjectProxy(target);return proxy.getProxy();}@Overridepublic Class<?> getObjectType() {return MyObject.class;}@Overridepublic boolean isSingleton() {return true;}// 设置目标对象的方法public void setTarget(MyObject target) {this.target = target;}
}
3.3 其他注意事项
1、bean的名称在IOC容器不可重复。2、使用bean标签配置bean。默认bean的名称为类路径。<bean class="com.hlp.spring.ioc.beans.Car" ></bean>ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");3、使用bean标签配置bean。可以使用id或name配置bean的名称。name配置bean的名称,可以配置多个名称。id配置bena的名称,只能配置一个。1)bean属性的id和name,是bean的唯一标识。2)同一个spring的配置文件中,不同bean的id和name是不能相同的。否则会报错。3)不同的spring配置文件中,id和name可以重复。此时spring针对相同的id或name采取的策略是根据DefaultListableBeanFactory类中的allowBeanDefinitionOverriding属性值来判断的。默认为true,即相同的id或name会被覆盖。如果设置为false,则会抛出异常。
1)使用bean标签配置bean。默认bean的名称为类路径。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 默认bean的名称为'com.hlp.spring.ioc.beans.Car' --><bean class="com.hlp.spring.ioc.beans.Car" ></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");System.out.println(car);}
}
2)使用bean标签配置bean。可以使用id或name配置bean的名称。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- <!– 使用name、id均可为bean命名。 –>--><bean class="com.hlp.spring.ioc.beans.Car" name="car1" id="car2" ></bean><bean class="com.hlp.spring.ioc.beans.Car" name="car3" ></bean></beans>
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car1");System.out.println(car);Car car2 = (Car)ac.getBean("car2");System.out.println(car);}
}
3)使用bean标签配置bean。name可以同时配置多个名称,id只能配置一个名称。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 默认bean的名称为'com.hlp.spring.ioc.beans.Car' -->
<!-- <bean class="com.hlp.spring.ioc.beans.Car" ></bean>--><!-- <!– 使用name、id均可为bean命名。 –>--><bean class="com.hlp.spring.ioc.beans.Car" name="car1,car2,car3" ></bean></beans>
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car1");System.out.println(car);Car car2 = (Car)ac.getBean("car2");System.out.println(car);}
}
4 Bean的依赖注入(DI)
DI:依赖注入(Dependency Injection)。 是 spring 框架核心IOC的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。
IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
这种业务层和持久层的依赖关系,在使用 spring 之后,让 spring 来维护。
简单的说,就是坐等框架把持久层对象传入业务层,而不用自己去获取。
4.1 构造注入
构造注入:通过构造方法实现属性的注入。第一步需要添加对应的有参构造方法,第二步在配置文件中添加对应的配置信息。方式一:<bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg name="id" value="1111"></constructor-arg><constructor-arg name="name" value="宝马xxx"></constructor-arg><constructor-arg name="age" value="1"></constructor-arg></bean>方式二:<bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg index="0" value="1111"></constructor-arg><constructor-arg index="1" value="宝马xxx"></constructor-arg><constructor-arg value="1"></constructor-arg></bean>方式三:【使用c标签,需引入c标签约束】<bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>方式四:【使用c标签,需引入c标签约束】<bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean>
1)构造注入
car.java
public class Car {private String id;private String name;private int age;public Car(String id, String name, int age) {this.id = id;this.name = name;this.age = age;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
applicationContext.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg name="id" value="1111"></constructor-arg><constructor-arg name="name" value="宝马xxx"></constructor-arg><constructor-arg name="age" value="1"></constructor-arg></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
2)构造注入
applicationContext.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!-- <constructor-arg name="id" value="1111"></constructor-arg>-->
<!-- <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!-- <constructor-arg name="age" value="1"></constructor-arg>-->
<!-- </bean>--><bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg index="0" value="1111"></constructor-arg><constructor-arg index="1" value="宝马xxx"></constructor-arg><constructor-arg value="1"></constructor-arg></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
3)构造注入-c简化【使用c标签简化】
applicationContext.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!-- <constructor-arg name="id" value="1111"></constructor-arg>-->
<!-- <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!-- <constructor-arg name="age" value="1"></constructor-arg>-->
<!-- </bean>--><!-- <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!-- <constructor-arg index="0" value="1111"></constructor-arg>-->
<!-- <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!-- <constructor-arg value="1"></constructor-arg>-->
<!-- </bean>--><bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
4)构造注入-c简化【使用c标签简化】
applicationContext.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!-- <constructor-arg name="id" value="1111"></constructor-arg>-->
<!-- <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!-- <constructor-arg name="age" value="1"></constructor-arg>-->
<!-- </bean>--><!-- <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!-- <constructor-arg index="0" value="1111"></constructor-arg>-->
<!-- <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!-- <constructor-arg value="1"></constructor-arg>-->
<!-- </bean>--><!-- <bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>--><bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
4.2 设值注入(set赋值)
通过set方法给属性赋值:<bean id="user" class="org.jsoft.c_property.User"><!-- 【setAge1111 -》age11111】 --><property name="age1111" value="12"></property></bean>切记:给实体类赋值,实质上是调用了实体类的的setXXX方法。【如果方法名称为setAge1111,则设置bean的属性时,属性名称为age11111】所以实体类赋值的变量必须有set方法,否则报错。【实体类赋值的成员变量,必须有set方法】
1)设值注入
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 设值注入:方式一 --><bean class="com.hlp.spring.ioc.beans.Car" id="car"><property name="id" value="12xxxx"></property><property name="age" value="12"></property><property name="name" value="12"></property></bean><!-- 设值注入:方式二 -->
<!-- <bean class="com.hlp.spring.ioc.beans.Car" id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>--></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
2)设值注入-p标签简化【必须引入p标签】
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 设值注入:方式一 -->
<!-- <bean class="com.hlp.spring.ioc.beans.Car" id="car">-->
<!-- <property name="id" value="12xxxx"></property>-->
<!-- <property name="age" value="12"></property>-->
<!-- <property name="name" value="12"></property>-->
<!-- </bean>--><!-- 设值注入:方式二 --><bean class="com.hlp.spring.ioc.beans.Car" id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean></beans>
4.3 赋值方式(根据赋值的类型来化分)
如果初始化的属性的类型是自定义的对象,那么注入的时候可以通过ref 属性来引用或者直接内置bean标签注入
1 基础赋值
1)value 赋值, 直接赋值基本类型数据
通过构造方法给属性赋值<bean id="user1" class="org.jsoft.c_property.User"><constructor-arg value="12" index="1"></constructor-arg><constructor-arg value="str" index="0"></constructor-arg></bean>通过set方法给属性赋值<bean id="user2" class="org.jsoft.c_property.User"><property name="name" value="王帅"></property> <property name="age1111" value="12"></property></bean>
2)ref 赋值,引用对象数据
通过构造方法给属性赋值<bean id="str" class="java.lang.String"><constructor-arg value="王帅"></constructor-arg></bean> <bean id="user1" class="org.jsoft.c_property.User"><constructor-arg value="12" index="1"></constructor-arg><constructor-arg ref="str" index="0"></constructor-arg></bean>通过set方法给属性赋值<bean id="str" class="java.lang.String"><constructor-arg value="王帅"></constructor-arg></bean> <bean id="user2" class="org.jsoft.c_property.User"><property ref="str" value="王帅"></property> <property name="age1111" value="12"></property></bean>
3)内部Bean 赋值
通过构造方法给属性赋值:<bean id="user1" class="org.jsoft.c_property.User"><constructor-arg value="12" index="1"></constructor-arg><constructor-arg ><bean class="java.lang.String"><constructor-arg value="sss"></constructor-arg></bean></constructor-arg></bean>通过set方法给属性赋值:<bean id="user2" class="org.jsoft.c_property.User"><!-- 【setName -》name】 --><property name="name" ><bean class="java.lang.String"><constructor-arg value="sss"></constructor-arg></bean></property><!-- 【setAge1 -》age1】 --><property name="age1111" value="12"></property></bean>
4)内部Bean+级联赋值
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1"><property name="personName" value="张三"></property></bean><bean class="com.hlp.demo02.User" id="user"><property name="name" value="张三"></property><property name="age" value="12"></property><property name="person" ref="person1" ></property><property name="person.personName" value="123"></property></bean>
</beans>
5)注入空值
<bean id="book3" class="run.arbor.spring5demo.Book"><property name="bname" value="Java核心技术"/><!-- 给bauthor设置空值 --><property name="bauthor"><null/></property></bean>
6)注入特殊符号
在property标签中使用value标签,并且使用CDATA的方式来注入参数,<![CDATA[参数]]>
<bean id="book4" class="run.arbor.spring5demo.Book"><property name="bname" value="Java核心技术"/><!-- 给bauthor设置值为<凯 S. 霍斯特曼>第一种方式:把<>进行转义, < 和 >第二种方式:使用CDATA方式,<![CDATA[参数]]>--><property name="bauthor"><value><![CDATA[<凯 S. 霍斯特曼>]]></value></property></bean>
2 集合赋值
1)list注入
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
User.java
public class User {private String name;private List<String> games;private List<Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getGames() {return games;}public void setGames(List<String> games) {this.games = games;}public List<Car> getCars() {return cars;}public void setCars(List<Car> cars) {this.cars = cars;}
}
applicationContext.java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User" name="user"><property name="name" value="12"></property><!-- list注入基本类型属性--><property name="games"><list><value>122</value><value>122xxx</value><value>122333ddd</value></list></property><!-- list注入引用类型属性--><property name="cars"><list><bean class="com.hlp.spring.ioc.beans.Car"></bean><bean class="com.hlp.spring.ioc.beans.Car"></bean></list></property></bean></beans>
2)arrary注入
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
User.java
public class User {private String name;private List<String> games;private List<Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getGames() {return games;}public void setGames(List<String> games) {this.games = games;}public List<Car> getCars() {return cars;}public void setCars(List<Car> cars) {this.cars = cars;}
}
applicationContext.java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User" name="user"><property name="name" value="12"></property><!-- array注入基本类型属性--><property name="games"><array><value>122</value><value>122xxx</value><value>122333ddd</value></array></property><!-- array注入引用类型属性--><property name="cars"><array><bean class="com.hlp.spring.ioc.beans.Car"></bean><bean class="com.hlp.spring.ioc.beans.Car"></bean></array></property></bean></beans>
3)map注入
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
User.java
public class User {private String name;private Map<String,String> games;private Map<String,Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public Map<String, String> getGames() {return games;}public void setGames(Map<String, String> games) {this.games = games;}public Map<String, Car> getCars() {return cars;}public void setCars(Map<String, Car> cars) {this.cars = cars;}
}
applicationContext.java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car"></bean><bean class="com.hlp.spring.ioc.beans.User" name="user"><property name="name" value="12"></property><!-- array注入基本类型属性--><property name="games"><map><entry key="a1" value="111"></entry><entry key="a2" value="111"></entry><entry key="a3" value="111"></entry></map></property><!-- array注入引用类型属性--><property name="cars"><map><entry key="a1" value-ref="car"></entry><entry key="a2" value-ref="car"></entry><entry key="a3" value-ref="car"></entry></map></property></bean></beans>
测试
public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
4)propertis赋值
User.java
public class User {private String name;private Properties properties;public String getName() {return name;}public void setName(String name) {this.name = name;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User" name="user"><property name="name" value="123"></property><property name="properties"><props><prop key="aaa" > 121212</prop><prop key="aaa2" > aaa</prop><prop key="aaa3" > bb</prop></props></property></bean></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user.getProperties());}
}
4)构建集合赋值
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1"><property name="personName" value="person1"></property></bean><bean class="com.hlp.demo02.Person" id="person2"><property name="personName" value="person2"></property></bean><bean class="com.hlp.demo02.Person" id="person3"><property name="personName" value="person3"></property></bean><util:list id="personList"><ref bean="person1"/><ref bean="person2"/><ref bean="person3"/></util:list><bean class="com.hlp.demo02.User" id="user"><property name="name" value="ssss" ></property><property name="personList" ref="personList"></property></bean></beans>
Person.java
public class Person {private String personName;public String getPersonName() {return personName;}public void setPersonName(String personName) {this.personName = personName;}
}
User .java
public class User {private String name;private int age;private List<Person> personList;set、get。。
}
App .java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());}
}
4 案例
案例1:ref引用对象
HelloDao.java
public class HelloDao {public User serach() {return new User();}
}
HelloService .java
public class HelloService {private HelloDao helloDao;public void setHelloDao(HelloDao helloDao) {this.helloDao = helloDao;}public User search() {return helloDao.serach();}
}
HelloController.java
public class HelloController {private HelloService helloService;public void setHelloService(HelloService helloService) {this.helloService = helloService;}public User execute() {return helloService.search();}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- ## 案例:模拟aciton / service / dao --><bean id="helloDao" class="org.jsoft.c_property.HelloDao"></bean><bean id="helloService" class="org.jsoft.c_property.HelloService"><property name="helloDao" ref="helloDao"></property></bean><bean id="helloAction" class="org.jsoft.c_property.HelloController"><property name="helloService" ref="helloService"></property></bean><!-- ## 案例2(内部Bean):模拟aciton / service / dao --><bean id="helloAction2" class="org.jsoft.c_property.HelloController"><property name="helloService"><bean class="org.jsoft.c_property.HelloService"><property name="helloDao"><bean class="org.jsoft.c_property.HelloDao"></bean></property></bean></property></bean></beans>
App.java
public class App {public static void main(String[] args) {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");//获取对象HelloController helloAction=(HelloController) ac.getBean("helloAction2");User user = helloAction.execute();System.out.println(user);}}
案例2:内部Bean创建对象
HelloDao.java
public class HelloDao {public User serach() {return new User();}
}
HelloService .java
public class HelloService {private HelloDao helloDao;public void setHelloDao(HelloDao helloDao) {this.helloDao = helloDao;}public User search() {return helloDao.serach();}
}
HelloController.java
public class HelloController {private HelloService helloService;public void setHelloService(HelloService helloService) {this.helloService = helloService;}public User execute() {return helloService.search();}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- ## 案例2(内部Bean):模拟aciton / service / dao --><bean id="helloAction2" class="org.jsoft.c_property.HelloController"><property name="helloService"><bean class="org.jsoft.c_property.HelloService"><property name="helloDao"><bean class="org.jsoft.c_property.HelloDao"></bean></property></bean></property></bean></beans>
App.java
public class App {public static void main(String[] args) {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");//获取对象HelloController helloAction=(HelloController) ac.getBean("helloAction2");User user = helloAction.execute();System.out.println(user);}}
案例3:构造注入使用ref注入对象
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
User.java
public class User {private String name;private Car car;public User(String name, Car car) {this.name = name;this.car = car;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><bean class="com.hlp.spring.ioc.beans.Car" id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" ><constructor-arg name="name" value="123"></constructor-arg><constructor-arg name="car" ref="car123"></constructor-arg></bean><!-- 构造注入使用c标签注入对象--><!-- 构造注入使用内部bean注入对象--><!-- 设值注入:方式二 --></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
}
案例4:构造注入使用c标签注入对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><!-- 构造注入使用c标签注入对象--><bean class="com.hlp.spring.ioc.beans.Car" id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" c:name="123" c:car-ref="car123"> </bean><!-- 构造注入使用内部bean注入对象--><!-- 设值注入:方式二 --></beans>
案例5:构造注入使用内部Bena注入对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><!-- 构造注入使用c标签注入对象--><!-- 构造注入使用内部bean注入对象--><bean class="com.hlp.spring.ioc.beans.User" id="user" ><constructor-arg name="name" value="12"></constructor-arg><constructor-arg name="car"><bean class="com.hlp.spring.ioc.beans.Car"></bean></constructor-arg></bean></beans>
案例6:属性注入使用ref注入对象
Car.java
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
User.java
public class User {private String name;private Car car;public String getName() {return name;}public void setName(String name) {this.name = name;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" ><property name="name" value="123"></property><property name="car" ref="car"></property></bean><!-- 属性注入使用c标签注入对象--><!-- 属性注入使用内部bean注入对象--></beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
}
5)属性注入使用p标签注入对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><!-- 属性注入使用c标签注入对象--><bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" p:name="123" p:car-ref="car"> </bean><!-- 属性注入使用内部bean注入对象--></beans>
6)属性注入使用内部Bena注入对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><!-- 属性注入使用c标签注入对象--><!-- 属性注入使用内部bean注入对象--><bean class="com.hlp.spring.ioc.beans.User" ><property name="name" value="12"></property><property name="car"><bean class="com.hlp.spring.ioc.beans.Car"></bean></property></bean></beans>
4.4 自动装配
autowire:自动装配属性byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入default:默认值,不自动装配
1)autowire=“byName”
按属性名称自动装配。 Spring寻找与需要自动装配的属性同名的bean。
例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(…)方法),那么Spring将查找一个名为master的bean定义并使用它来设置该属性。
<bean id="book" class="com.dhy.Factory.Book"><property name="name"><value>时间简史</value></property><property name="money" value="50"/>
</bean><bean id="Obj" class="com.dhy.Factory.Obj" autowire="byName">
>>>>>> 案例
Person.java
public class Person {private String personName;set/get}
User .java
public class User {private String name;private int age;private Person person123;set/get
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"><property name="personName" value="123"></property></bean><!-- autowire="byName"。自动给person123属性赋值--><bean class="com.hlp.demo02.User" id="user" autowire="byName"><property name="name" value="12333"></property><property name="age" value="12"></property><!-- <property name="person123" ref="person123"></property> --></bean>
</beans>
App.java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getPerson123().getPersonName());}
}
2)autowire=“byType”
如果容器中恰好存在一个属性类型的bean,则使该属性自动装配。
如果存在多个,则将引发致命异常,这表明您可能无法对该bean使用byType自动装配。如果没有匹配的bean,则什么都不会发生(未设置该属性)。
以属性的类型,即Book.class,作为作为查找依据,去容器中找到这个组件
<bean id="Obj" class="com.dhy.Factory.Obj" autowire="byType">
>>>>>> 案例
Person.java
public class Person {private String personName;set/get}
User .java
public class User {private String name;private int age;private Person person;set/get...
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"><property name="personName" value="123"></property></bean><!-- autowire="byName"。自动给person123属性赋值--><bean class="com.hlp.demo02.User" id="user" autowire="byType"><property name="name" value="12333"></property><property name="age" value="12"></property><!-- <property name="person123" ref="person123"></property> --></bean>
</beans>
App.java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getPerson().getPersonName());}
}
3)自动装配全局配置
也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName"> 根据名称自动装配(全局)<!-- ###############自动装配############### --> <bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean> <bean id="userService" class="cn.itcast.d_auto.UserService"></bean><bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean></beans>
5 Bean的作用域
scope:指定对象的作用范围singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象prototype:多例的,调用getbean方法时候创建request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 session
1)单例
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1" scope="singleton"><property name="personName" value="person1"></property></bean></beans>
App.java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Person bean1 = ac.getBean(Person.class);Person bean2 = ac.getBean(Person.class);System.out.println("bean1"+bean1);System.out.println("bean2"+bean2);}
}
2)多例
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1" scope="prototype"><property name="personName" value="person1"></property></bean></beans>
App.java
public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Person bean1 = ac.getBean(Person.class);Person bean2 = ac.getBean(Person.class);System.out.println("bean1"+bean1);System.out.println("bean2"+bean2);}
}
6 Bean的生命周期
<bean id="user" class="org.jsoft.a_hello.User" init-method="user_init" destroy-method="user_destoty" ></bean>init-method="init_user" 对应对象的init_user方法,在对象创建爱之后执行destroy-method="xxx" 在调用容器对象的destriy方法时候执行,(只有容器用实现类,才能调用容器的销毁方法)
>>>>>> 案例
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="org.jsoft.a_hello.User" init-method="user_init" destroy-method="user_destoty" ></bean></beans>
User.java
public class User {private String name;private int age;public User() {super();System.out.println("对象创建完毕");}public void user_init() {System.out.println("创建对象之后,初始化");}public void user_destoty(){System.out.println("IOC容器销毁,调用");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
App.java
public class App_bean {@Testpublic void testIOC() {//加载配置文件,创建Bean工程//ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");//加载配置文件,创建Bean工程【用容器对象的实现类,因为要调用容器的销毁方法】ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");System.out.println("---IOC容器初始化完毕---");//获取对象User u=(User) ac.getBean("user");System.out.println(u);//销毁IOC容器ac.destroy();}
}
7 applicationContext总分配置文件
总分配置文件配置
>>>>>> bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><import resource="resource/bean-base.xml"/><import resource="resource/bean-dao.xml"/><import resource="resource/bean-service.xml"/><import resource="resource/bean-controller.xml"/></beans>
>>>>>> resource/bean-base.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 1) 连接池对象实例 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="user" value="root"></property><property name="password" value="root"></property><property name="initialPoolSize" value="3"></property><property name="maxPoolSize" value="6"></property><property name="maxIdleTime" value="1000"></property></bean><!-- 2) SessionFactory对象实例 --><!-- ### >>> 方式 3所有的配置全部都在Spring配置文件中完成 --><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><!-- ## 注入连接池对象 --><property name="dataSource" ref="dataSource"></property><!-- ## hibernate常用配置 --><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property><!-- hibernate映射配置 <property name="mappingLocations"><list><value>classpath:cn/itcast/entity/*.hbm.xml</value></list></property>--><!-- ## hibernate映射配置 --><property name="mappingDirectoryLocations"><list><value>classpath:org/hlp/entity</value></list></property></bean><!-- 3) 事务配置 --><!-- ## a.配置事务管理器 --><bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"></property></bean><!-- ## b.配置事务增强 --><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="get*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*" read-only="false"/></tx:attributes></tx:advice><!-- ## c.配置Aop --><aop:config ><!-- 定义切入点表达式 --><aop:pointcut expression="execution(* org.hlp.dao.*.*(..))" id="pt"/><!-- 相当于aop:acpect中定义的环绕通知 --><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config><bean id="adminDao" class="org.hlp.dao.AdminDao"><property name="sf" ref="sessionFactory"></property></bean></beans>
>>>>>> resource/bean-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="adminDao" class="org.hlp.dao.AdminDao"><property name="sf" ref="sessionFactory"></property></bean><bean id="deptDao" class="org.hlp.dao.DeptDao"><property name="sf" ref="sessionFactory"></property></bean><bean id="empDao" class="org.hlp.dao.EmpDao"><property name="sf" ref="sessionFactory"></property></bean></beans>
>>>>>> resource/bean-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="adminService" class="org.hlp.service.impl.AdminService"><property name="adminDao" ref="adminDao"></property></bean><bean id="empService" class="org.hlp.service.impl.EmpService"><property name="empDao" ref="empDao"></property></bean><bean id="deptService" class="org.hlp.service.impl.DeptService"><property name="deptDao" ref="deptDao"></property></bean></beans>
三、基于XML配置方式+注解方式的实现
3.1 基础实现
1)添加AOP依赖支持
在使用xml方式时,核心包只需要使用core、beans、context、jar。基于注解的方式需要用到AOP的支持,所以我们需要添加AOP的依赖。
2)添加扫描
通过context标签component-scan属性指定扫描路径
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan>
</beans>
3)使用@Component注解
Car.java
@Component
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
4)测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);}
}
3.2 context:component-scan标签,开启注解扫描
context:component-scan标签,配置扫描路径。
1、使用步骤1)先引入context名称空间xmlns:context="http://www.springframework.org/schema/context"2)开启注解扫描<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>3)使用注解通过注解的方式,把对象加入ioc容器。2、使用1)使用context:component-scan标签可以指定一个或多个容器扫描路径。2)使用context:component-scan标签可以指定扫描哪些对象。
1)使用context:component-scan标签指定多个容器扫描路径
方式一:使用多个context:component-scan标签指定多个配置包
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-----><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan><context:component-scan base-package="com.hlp.spring.ioc.beans2"></context:component-scan></beans>
方式二:使用一个context:component-scan标签指定多个配置包
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-----><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans,com.hlp2"></context:component-scan></beans>
2)使用context:component-scan标签配置注解生效
使用context:component-scan开启注解扫描。配置只扫描哪个注解。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><!--不使用@Component、@Controller、@Service、@Repository注解。--><context:component-scan base-package="com.hlp.spring.ioc.beans" use-default-filters="false"></context:component-scan><!--不使用@Component、@Controller、@Service、@Repository注解。仅使用@Component--><context:component-scan base-package="com.hlp.spring.ioc.beans" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/></context:component-scan></beans>
使用context:component-scan开启注解扫描。配置不扫描哪个注解。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!--使用@Component、@Controller、@Service、@Repository注解。默认值。--><context:component-scan base-package="com.hlp.spring.ioc.beans" use-default-filters="true"></context:component-scan><!--使用@Component、@Controller、@Service、@Repository注解。@Controller注解除外--><context:component-scan base-package="com.hlp.spring.ioc.beans" use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan></beans>
3.3 @Component、@Controller、@Service、@Repository注解
1、使用@Component、@Controller、@Service、@Repository标注类,用于注册IOC容器。注解后可以被spring框架所扫描并注入到spring容器来进行管理 【相当于spring配置文件中的bean标签。】2、使用方式:标注类时,默认bean的名称为标注类的‘首字母小写形式’。同时也可以指定bean的名称。1)bean的名称为car。 @Componentpublic class Car {...}2)bean的名称为car111。 @Component("car111")public class Car {...}
1)区别
1、@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。 2、@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。 3、@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。4、@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能,当你的一个类被@Component所注解,那么就意味着同样可以用@Repository, @Service, @Controller来替代它,同时这些注解会具备有更多的功能,而且功能各异。
2)使用
>>>>>> 默认bean的名称类名首字母小写
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>
Car.java
@Component
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);}
}
>>>>>> 指定bean的名称
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>
Car.java
@Component("car123")
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car123");System.out.println(car);}
}
3.4 @Resource注解和@Autowire
在注解的场景下依赖注入我们可以通过 @Resource和@Autowired实现.
他们的区别是@Resource默认是根据name属性来查找的,
而@Autowired注解默认是根据类型査找的,@Autowired需要和@Qualifier配合实现基于name的查找
@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。
@Resource 注解和 @Autowired 注解都是在 Spring Framework 中进行依赖注入的注解,但它们之间有一些区别:1. 来源不同:@Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。@Resource 注解是由 Java EE 提供的注解,它定义在 javax.annotation.Resource 包下。@Autowired 注解是由 Spring 提供的注解,它定义在 org.springframework.beans.factory.annotation.Autowired 包下。2. 依赖注入策略不同:@Autowired默认按类型装配。@Resource默认按照名称进行装配。@Resource 注解默认按照名称进行依赖注入,如果有多个具有相同类型的依赖,可以使用 name 属性指定依赖的名称。@Autowired 注解默认按照类型进行依赖注入,如果有多个具有相同类型的依赖,可以使用 @Qualifier 注解或者 @Primary 注解指定依赖的名称或主要依赖。3. 注解属性不同: @Resource 注解可以添加 name 属性来指定依赖的名称,还可以添加 mappedName 属性来指定依赖的 JNDI 名称。@Autowired 注解可以添加 required 属性来指定依赖是否必须,默认为 true。
3.4.1 @Resource
@Resource注解:1、@Resource 是 Java EE 的注解之一,它用于进行依赖注入。2、@Resource 注解可以应用于字段、方法上。 >>> @Resource标注成员变量,查找IOC容器(默认根据变量名称),给变量赋值。 >>> @Resource标注方法,查找IOC容器(默认根据方法参数名),给方法的参数赋值。【标注的方法只能有一个参数,否则报错】3、使用方式 1)不写name属性: @Resourcea、默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。b、当注解写在字段上时,默认取字段名进行按照名称查找。 c、如果注解写在xxx方法上,默认取参数的名称进行装配。【xxx方式仅支持一个参数,否则报错】2)写name属性: @Resource(name="xxxx") 指定名称,仅能按照byName的方式进行匹配注入。如果找不到,则报错。
3.4.1.1 使用详解
1)@Resource标注在成员变量上@Resource标注在成员变量上:默认查询IOC容器中name或id为"person123"的对象,如果有,则注入。如果没有,则按照类型查找。@Resourceprivate Person person123;@Resource(name="personz")标注在成员变量上:查询IOC容器中name或id为"personz"的对象,如果有,则注入。如果没有,则报错。@Resource(name="personz")private Person person;
3)@Resource标注在方法:@Resource标注在方法:查询IOC容器中name或id为"personX1"的对象,如果有,则注入。如果没有,则根据类型查找。@Resourcepublic void m1(Person personX1){}@Resource(name="personz")标注在方法:查询IOC容器中name或id为"personz"的对象,如果有,则注入。如果没有,则报错。@Resource(name="personz")public void m1(Person person){}
1)@Resource 默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>
MySomeService.java
@Component
public class MySomeService {@Resourceprivate Person person;public void print(){System.out.println(person);}
}
测试
@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
2)@Resource(name=“xxxx”) 指定名称,则只能根据名称查找。找不到,则会报错。
User.java
@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
ServiceImpl.java
@Component
public class ServiceImpl {@Resource(name="abc123")private User user;public User getUser() {return user;}
}
测试
@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}
3.4.1.2 案例
>>>>>> @Resource标注成员变量
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>
MySomeService.java
@Component
public class MySomeService {@Resourceprivate Person person123;public void print(){System.out.println(person);}
}
App .java
@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource标注方法
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>
MySomeService.java
@Component
public class MySomeService {private Person person123;@Resource public void xxx(Person person123){this.person123=person123;}public void print(){System.out.println(person);}
}
App .java
@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource(name = “person123”)标注成员变量
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>
MySomeService.java
@Component
public class MySomeService {@Resource(name = "person123")private Person person;public void print(){System.out.println(person);}
}
App .java
@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource(name = “person123”)标注方法
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>
MySomeService.java
@Component
public class MySomeService {private Person person123;@Resource(name = "person123")public void xxx(Person person123){this.person123=person123;}public void print(){System.out.println(person);}
}
App .java
@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
3.4.2 @Autowired
@Autowired注解:1、spring提供注解。注入时,默认根据bean的类型查找。同时也可以指定名称查找。2、@Autowired 注解可以应用于标注在成员变量、构造方法、普通方法上。
3、使用1)@Autowired:按照类型查找@Autowired 标注成员变量:查找IOC容器【与变量同类型的对象】,并注入 @Autowiredprivate Person person;@Autowired 标注构造方法:查找IOC容器【与构造方法的参数同类型的对象】,并注入 @Autowiredpublic MySomeService(Person person2){this.person=person2;} @Autowired 标注方法:查找IOC容器【与方法的参数同类型的对象】,并注入 @Autowiredpublic void ser(Person person123){this.person=person123;}注意:方法可以无参。IOC初始化后也会调用该方法。类似于init-method@Autowiredpublic void ser(){system.out.print("123")}1)@Autowired配合@Qualifier("xxx")。按照指定名称查找@Autowired+@Qualifier("person123")标注成员变量:根据指定名称查找IOC容器中对象,并注入 @Autowired@Qualifier("person123")private Person person123;@Autowired+@Qualifier("person123")标注方法:查找IOC容器中同类型的对象,并注入 @Autowired@Qualifier("person123")public void ser(Person person123){this.person=person123;}@Autowired+@Qualifier("person123")不能标注构造方法
1)@Autowired 默认根据类型查找。
User.java
@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
ServiceImpl.java
@Component
public class ServiceImpl {@Autowiredprivate User user;public User getUser() {return user;}
}
测试
@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}
2)@Autowired + @@Qualifier(name=“xxx”) 根据名称查找
User.java
@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
ServiceImpl.java
@Component
public class ServiceImpl {@Autowired@Qualifier("abc123")private User user;public User getUser() {return user;}
}
测试
@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}
四、基于JavaConfig配置类方式的实现
在Spring3.x之后开始支持]ava配置类的形式,从而舍弃配置文件的方式。
4.1 基本实现
Java配置文件需要通过@Configuration注解标注,需要加载的实例需要通过@Bean注解标注
1)MyConfig.java 配置类
@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User user(){return new User();}
}
2)Car.java
@Component
public class Car {private String id;private String name;private int age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
3)User.java
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
4)测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);User user = (User)ac.getBean("user");System.out.println(user);}
}
4.2 AnnotationConfigApplicationContext容器
AnnotationConfigApplicationContext作用:加载配置类,创建IOC容器。
1、指定配置类,创建IOC容器1)使用AnnotationConfigApplicationContext创建IOC容器,指定配置类。2)配置类必须被@Configuration或@Comonent、@Controller等价注解所标注。配置类的作用相当于applicatonContext.xml配置文件3)基础用法a、指定一个或多个配置类,创建IOC容器ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class,MyConfig2.class);c、指定一个或多个扫描路径,创建IOC容器ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc");ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc","com.hlp.spring.ioc2");2、不指定配置类,创建IOC容器。【手动注册配置类】//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();
1)指定配置类,注册IOC容器
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);}
}
2)不指定配置类,注册IOC容器。手动注册配置类
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();Object dev = ac.getBean("dev");System.out.println(dev);}
}
4.3 @Configuration Java配置类
1、使用@Configuration的作用:配置java配置类。相当于spring配置文件。2、@Configuration与@Compoonent、@Controller、@Service、@Repository注解等价。
案例
@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User user(){return new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);User user = (User)ac.getBean("user");System.out.println(user);}
}
4.4 @ComponentScan、@ComponentScans注解,配置扫描包
1、@ComponentScan或@ComponentScans作用:1)在基于java配置类的方式中,一般结合@Configuration使用,实现IOC容器。 2)用于配置扫描路径。相当于applicationContext.xml中的context:component-scan标签。
2、@ComponentScan指定扫描路径,可以指定包名,也可以指定xxx.class类文件指定包名:扫描当前包下的文件以及子包文件,创建Bean。指定类文件:扫描当前类所在包的文件及其子包文件,创建Bean。1)默认扫描当前标注类所在包及其子包的类。@ComponentScan2)指定一个扫描路径@ComponentScan("com.hlp.spring.ioc.beans")@ComponentScan({"com.hlp.spring.ioc.beans"})@ComponentScan(basePackages = "com.hlp.spring.ioc.beans")@ComponentScan(basePackages = {"com.hlp.spring.ioc.beans"})3)指定多个扫描路径@ComponentScan({"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})@ComponentScan(basePackages = {"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})4)指定一个或多个类文件@ComponentScan(basePackageClasses={Car.class})@ComponentScan(basePackageClasses={Car.class,User.class})3、@ComponentScan其他属性@Configuration@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=false,includeFilters ={@ComponentScan.Filter(Controller.class)} )public class MyConfig {@Bean("myUser")public User myUser(){return new User();}}
4、使用@ComponentScans指定扫描路径,作用与@ComponentScan等价
1)使用@ComponentScan指定扫描路径
MyConfig.java
@Configuration
@ComponentScan("com.hlp.spring.ioc.beans")
public class MyConfig {@Bean("myUser")public User myUser(){return new User();}
}
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2)使用@ComponentScans指定扫描路径
MyConfig.java
@Configuration
@ComponentScans({@ComponentScan({"com.hlp.spring.ioc"}),@ComponentScan({"com.hlp.spring.ioc.beans"})
}) public class MyConfig {@Bean("myUser")public User myUser(){return new User();}
}
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
3)属性示例
MyConfig.java
@Configuration
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=false,includeFilters ={@ComponentScan.Filter(Controller.class)} )
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=true,excludeFilters ={@ComponentScan.Filter(Controller.class)} )
public class MyConfig {@Bean("myUser")public User myUser(){return new User();}
}
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
4.5 @Bean注解
@Bean1、相当于applicationContext中的bean标签。2、一般在@Configuration标注的类中使用。由于@Configuration与其他@Component等标签等价,所以也可以在@Component等标签中标注的类中使用。3、默认注册的bean的名称为标注的方法名。同时也可以指定bean的名称默认注册bean的名称为方法名myUser@Beanpublic User myUser(){return new User();}指定bean的名称为abc123@Bean("abc123")public User myUser(){return new User();}4、@Bean标注的方法有参数,会自动注入参数对象。1)@Bean标注的方法可以有多个参数。spring默认会根据参数类型查找IOC容器注入参数。如果找不到,就报错。2)@Bean标注的方法可以有多个参数。通过@Qualifier("name")注解标注参数,spring会根据名称查找IOC容器注入参数。如果找不到,就报错。
1) 默认注册的bean的名称为标注的方法名
@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User myUser(){return new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
// Car car = (Car)ac.getBean("car");
// System.out.println(car);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2) 指定bean的名称
@Configuration
@ComponentScan
public class MyConfig {@Bean("abc123")public User myUser(){return new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
// Car car = (Car)ac.getBean("car");
// System.out.println(car);User user = (User)ac.getBean("abc123");System.out.println(user);}
}
3) @Bean标注有多个参数方法,默认会根据参数类型查找IOC并将对象注入到参数中
DataSourceConfig.java
@Component("abc")
public class DataSourceConfig {@Beanpublic DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Beanpublic JdbcTemplate testBean(DataSource aa, DataSource a3){System.out.println(aa);System.out.println(a3);return null;}}
App.java
@Component
@ComponentScan
public class App {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);}
}
4) @Bean标注有多个参数方法,通过(@Qualifier(“springDS2”)标注参数,会根据名称查找IOC并将对象注入到参数中
DataSourceConfig.java
@Component("abc")
public class DataSourceConfig {@Bean("db1")public DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Bean("db2")public DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Beanpublic JdbcTemplate testBean((@Qualifier("db1")DataSource aa){System.out.println(aa);return null;}}
App.java
@Component
@ComponentScan
public class App {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);}
}
4.6 @Conditional、@Profile条件注解
1 @Conditional
@Conditional注解:配置@Bean注解使用,决定是否将注册的Bean注入到IOC容器中1、使用步骤1)编写一个类MyConditional,实现Condition接口中的matches方法。2)使用@Conditional(MyConditional.class)进行标注注册的bean。3)如果MyConditional实现的matches返回true,则注入标注bean,如果为false,则不注入标注bean。2、使用方式1)指定一个条件//如果MyConditional中的matches方法返回true,则注入。否则不注入。@Conditional(MyConditional.class)//如果MyConditional中的matches方法返回true,则注入。否则不注入。@Conditional({MyConditional.class}) 2)指定两个条件//如果MyConditional和MyConditional2中的matches方法都返回true,则注入。否则不注入。@Conditional({MyConditional.class,MyConditional2.class})
1)自定义MYConditional类,实现Condition接口。
该方法返回true,则允许注册标注bean。否则不允许注册标注bean。
public class MYConditional implements Condition {//matches方法逻辑:加载“com.hlp.spring.ioc.User”类。如果为空,则返回false。如果不为空,则返回true@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {ClassLoader classLoader = conditionContext.getClassLoader();try {Class<?> clazz = classLoader.loadClass("com.hlp.spring.ioc.User");if(clazz!=null){return true;}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}return false;}
}
2)配置使用条件
@Configuration
@ComponentScan
public class MyConfig {@Bean("myUser")@Conditional({MYConditional.class})public User myUser(){return new User();}
}
3)测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2 @Profile 注解
@Profile 注解:1、@Profile注解继承了@Conditional条件注解,同时指定了条件类。@Conditional({ProfileCondition.class})2、条件类ProfileCondition.class是Spring提供的,内置的条件类。其作用是读取Environment中的activeProfile属性设置的值。与@Profile指定的值进行比较。如果相同,则注入该bean。如果不同,则不注入。
1)作用
@Profile使用时,指定value值。
@Profile注解源码:
该注解继承了@Conditional注解。@Conditional注解中也指定了条件类ProfileCondition.class
ProfileCondition源码
该条件类的作用是:读取环境变量中的activeProfile属性,与当前@Profile指定值比较,如果相同,则返回true,即允许注入。否则不允许注入。
2)使用案例
Datasource.java
public class Datasource {private String url;private String password;private String name;public Datasource(String url, String password, String name) {this.url = url;this.password = password;this.name = name;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Datasource{" +"url='" + url + '\'' +", password='" + password + '\'' +", name='" + name + '\'' +'}';}
}
MyConfig.java
@Configuration
public class MyConfig {//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与“dev”相同,则注入该bean。@Bean("ds")@Profile("dev")public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与“pro”相同,则注入该bean。@Bean("ds")@Profile("pro")public Datasource datasource2(){return new Datasource("jdbc:mysql://127.0.0.1/pro","123333","12333");}
}
测试
指定环境变量属性为pro。那么 @Profile(“pro”)标注的,则生效。
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//设置对应的环境信息ac.getEnvironment().setActiveProfiles("pro");//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();Object dev = ac.getBean("ds");System.out.println(dev);}
}
4.7 Bean的作用域
1、通过bean标签或通过@Bean注解注入的bean,默认情况下均为单例模式。即多次调用getBean(),获取的对象都是同一个对象。可通过scope进行设置。 2、scope用于设置bean的作用域。scope="singleton" 单例模式,默认值。scope="prototype" 原型模式。
3、bean标签作用域设置:1)使用spring配置文件配置bean。默认为单例。<bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>2)基础设置设置单例模式,可省略,默认值。<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>设置多例模式<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
4、@Bean注解作用域设置:1)使用@Bean配置bean。默认为单例。@Bean("ds" )public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}2)基础设置设置单例模式方式一@Bean("ds" )@Scopepublic Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}方式二@Bean("ds" )@Scope("singleton")public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}设置多例模式@Bean("ds" )@Scope("prototype")public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}
1 基于xml配置,作用域详解
1)默认情况下为单例模式
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
</beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}
2)通过scope属性设置单例作用域(默认,可省略)
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>
</beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}
3)通过scope属性设置多例作用域
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
</beans>
测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}
2 基于JavaConfig配置,作用域详解
1)默认情况下为单例模式
MyConfig.java
@Configuration
public class MyConfig {@Bean("ds" )public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}
测试
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}
2)通过scope设置单例作用域(默认,可省略)
MyConfig.java
@Configuration
public class MyConfig {@Bean("ds" )@Scope("singletone")public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}
测试
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}
3)通过scope属性设置多例作用域
MyConfig.java
@Configuration
@Configuration
public class MyConfig {@Bean("ds" )@Scope("prototype")public Datasource datasource1(){return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}
测试
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}
Spring框架提供了一系列的生命周期注解,用于管理bean对象的创建、初始化和销毁过程。下面是对一些常用的生命周期注解进行详解:@PostConstruct:该注解被标注在方法上,表示在对象创建完成并且属性注入完成后执行。通常用于执行一些初始化操作。@PreDestroy:该注解也被标注在方法上,表示在对象销毁之前执行。通常用于执行一些资源释放的操作。@Autowired:该注解用于自动注入依赖对象。当容器中存在多个相同类型的bean时,可以结合@Qualifier注解指定具体的bean。@Qualifier:该注解与@Autowired注解结合使用,用于指定注入的具体bean。可以通过指定bean的名称或者自定义的限定符来确定注入的对象。@Resource:该注解也用于自动注入依赖对象,可用于注入其他bean、属性、方法或者配置文件等。它支持根据名称进行注入,默认按照byName方式查找,如果找不到对应的bean,则按照byType方式查找。@Value:该注解用于注入属性值,可以直接注入基本类型、字符串、数组、集合以及其他bean对象等。@Component:该注解用于将类标识为一个组件,表示该类将由Spring容器进行管理,可通过扫描@ComponentScan注解指定的包路径进行自动扫描。@Controller、@Service、@Repository:这些注解分别用于标识控制层、服务层和数据访问层的组件,是@Component的特殊化,用于更细粒度地描述组件的职责。@Configuration:该注解用于标识配置类,表示该类是一个配置类,其中可能包含@Bean注解用于定义bean对象。@Bean:该注解用于标识方法,表示将方法返回的对象注册为一个bean,可以指定bean的名称、作用域、依赖关系等。
这篇关于一、Spring基础 --- 基础内容(一) (咕P4)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!