基于XML的使用
IoC配置
在spring的XML文件中通过一个bean标签,完成IoC的配置。
bean标签介绍
-
bean标签作用: 用于配置被spring容器管理的bean的信息。默认情况下它调用的是类中的【无参构造函数】,如果没有无参构造函数则不能创建成功。
-
bean标签属性
-
id:给对象在容器中提供一个唯一标识,用于获取对象。
-
class:指定类的全限定名,用于反射创建对象,默认情况下调用无参构造函数。
-
init-method:指定类中的创始化方法名称。
-
destroy-method:指定类中销毁方法名称,比如DataSource的配置中一般需要指定destroy-method="close"
-
scope:指定对象的作用范围。
-
singleton:默认值,单例的(在整个容器中只有一个对象),生命周期如下:
- 对象出生:当应用加载,创建容器时,对象就被创建了。
- 对象活着:只要容器在,对象就一直活着。
- 对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
-
prototype:多例的,每次访问对象时,都会重新创建对象实例,生命周期如下:
- 对象出生:当使用对象时,创建新的对象实例。
- 对象活着:只要对象在使用中,就一直活着。
- 对象死亡:当对象长时间不用时,被Java的垃圾回收器回收了。
-
request:将spring创建的Bean对象存入request域中。
-
session:将spring创建的Bean对象存入session域中。
-
global session:WEB项目中,应用在Protlet环境,如果没有Protlet环境那么globalSession相当于session。
-
-
bean实例化的三种方式
-
第一种:使用默认无参构造函数(重点)
在默认情况下:它会根据默认无参构造函数来创建对象。 若bean中没有默认无参构造函数,将会创建失败。
<bean id="id" class="com.XXX.XXX"/> -
第二种:静态工厂(了解)
使用StaticFactory类中的静态方法createbean创建对象,并存入spring容器:
/** *模拟一个静态工厂,创建对象 */ public class StaticFactory{ public static Bean createbean(){ return new Bean(); } }<bean id="XXX" class="com.XXX.XXX.StaticFactoty" factory-method="createbean"></bean> -
第三种:实例工厂(了解)
先把工厂创建交给spring来管理,然后再使用工厂的bean来调用里面的方法
/** *模拟一个实例工厂,创建对象 *此工厂创建对象,必须先有工厂实例对象,再调用方法 */ public class IntanceFactory{ public static Bean createbean(){ return new Bean(); } }<bean id ="instancFactory" class="com.XXX.XXX.IntanceFactory"> </bean><bean id ="XXX" factory-bean="instancFactory" factory-method="createbean"> </bean>
DI配置
依赖
- 依赖指的就是Bean实例中的属性
- 依赖(属性)分为:简单类型(8种基本类型和String类型)的属性、POJO类型的属性、集合数组类型的属性。
依赖注入
- 依赖注入:Dependency Injection。它是 spring 框架核心IoC的具体实现。
进行依赖注入
- 我们的程序在编写时,通过控制反转,把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况。
- 那如果一个bean包含了一些属性,那么spring帮我们实例化了bean对象之后,也需要将对应的属性信息进行赋值操作,这种属性赋值操作,就是所谓的依赖注入(获取值,注入属性)
依赖注入的方式
- 构造函数注入 使用类中的构造函数,给成员变量赋值。注意赋值的操作不是我们自己做的,而是通过配置方式,让spring框架来为我们注入。
public class User{
private int id;
private String name;
public User(int id,String name){
this.id = id;
this.name = name;
}
}
<bean id="user" class="com.XXX.XXX.User">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="张三"></constructor-arg>
</bean>
使用构造的方式,给对象的属性传值要求:类中需要提供一个对应参数列表的构造函数
涉及的标签:
-
constructor-arg
- index:指定参数在构造函数列表的索引位置
- name:指定参数在构造函数中的名称
- value:它能赋的值时基本数据类型和String类型
- ref:它能赋的值时其他bean类型,也就是说,必须的是在配置文件中配置过的bean
-
set方法注入(重点)
-
手动装配方式(XML方式)
- 需要配置bean标签的子标签property
- 需要配置的bean中指定setter方法
-
自动装配方式(注解方式)
-
@Autowired
- 作用一:查找实例,从spring容器中根据Bean的类型(byType)获取实例
- 作用二:赋值,将找到的实例,装配给另一个实例的属性值
- 注意事项:一个Java类型在同一个spring容器中,只能有一个实例
-
@Resource
- 作用一:查找实例,从spring容器中根据Bean的名称(byName)获取实例
- 作用二:赋值,将找到的实例,装配给另一个实例的属性值
-
@Inject
-
-
-
使用p名称注入数据
-
本质上还是调用set方法
-
步骤一:需要先引入p名称空间
在schema的名称空间加入该行:xmlns:p="http://www.springframework.org/schema/p" -
步骤二:使用p名称空间的语法
P:属性名 = "" p:属性名-ref = "" -
-
依赖注入不同类型的属性
- 简单类型(value)
<bean id="user" class="com.XXX.XXX.User">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="张三"></constructor-arg>
</bean>
- 引用类型(ref)
<bean id="user" class="com.XXX.XXX.User">
<property name ="car" ref="car"></property>
</bean>
<bean id="car" class="com.XXX.XXX.Car"></bean>
-
集合类型(数组)
- 如果是数组或者list集合,注入配置文件的方式是一样的
<bean id="user" class="com.XXX.XXX.User"> <property name="arrs"> <list> <!-- 如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签 --> <value>123</value> <value>aaa</value> <bean></bean> </list> </property> </bean>- 如果是Set集合,注入的配置文件方式如下:
<bean id="user" class="com.XXX.XXX.User"> <property name="sets"> <set> <!-- 如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签 --> <value>123</value> <value>aaa</value> <bean></bean> </set> </property> </bean>- 如果是Map集合,注入的配置方式如下
<bean id="user" class="com.XXX.XXX.User"> <property name="map"> <map> <!-- 如果集合内是简单类型,使用value,如果是POJO类型,则使用ref --> <entry key="key1" value="23"/> <entry key="key2" ref=""> </map> </property> </bean>- 如果是Properties集合的方式,注入的配置如下:
<bean id="user" class="com.XXX.XXX.User"> <property name="pro"> <props> <prop key="name">张三</prop> </props> </property> </bean>
基于注解和XML混合方式的使用
IoC注解使用方法
- 第一步:spring配置文件中,配置context:component-scan标签
- 第二步:类上面加上注解@Component,或者它的衍生注解@Controller、@Service、@Repository
常用注解
IoC注解
-
相当于
<bean id="" class=""></bean> -
Component注解
- 作用:把资源让spring来管理,相当于在xml中配置一个bean。
- 属性:value:指定bean的id,如果不指定value属性,默认bean的id是当前类的类名,首字母小写。
-
@Controller、@Service、@Repository注解
它们三个注解都是针对@Component的衍生注解,它们的作用及属性是一模一样的。它们只不过是提供了更加明确的语义化。
注意:如果注解中有且只有一个属性要赋值时,且名称是value,value在赋值时可以不写
- @Controller:一般用于表现层的注解
- @Service:一般用于业务层的注解
- @Repository:一般用于持久层的注解
DI注解(依赖注入)
-
相当于:
<property name="" value=""></property> <property name="" ref=""></property> -
@Autowired
- @Autowired默认是按类型装配(byType)
- @Autowired是由AutowiredAnnotationBeanPostProcessor类实现
- @Autowired是spring自带的注解
- @Autowired默认情况下要求依赖对象必须存在,如果需要允许null值,可以设置它的required属性为false,如:@Autowired(required=false)
- 如果我们想按名称装配(byName)可以结合@Qualifier注解进行使用
-
@Qualifier
- 在自动按照类型注入的基础之上,再按照Bean的id注入
- 它在给字段注入是不能独立使用,必须和@Autowire一起使用
- 但是给方法参数注入时,可以独立使用
-
@Resource
- @Resource默认按名称装配(byName),可以通过@Resource的name属性指定名称,如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,当找不到与名称匹配的bean时才按照类型进行装配
- @Resource属于J2EE JSR250规范的实现
- 但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配
推荐使用@Resource注解,因为它属于J2EE的,减少了与spring的耦合。
-
@Inject
- @Inject是根据类型进行自动装配的,如果需要按照名称进行装配,则需要配合@Name
- @Inject是在JSR303中的规范,需要导入javax.inject.Inject,实现注入
- @Inject可以作用在变量、setter方法、构造函数上
-
@Value
- 给基本类型和String类型注入值
- 可以使用占位符获取属性文件中的值
-
@Autowired、@Resource、@Inject 区别
- @Autowired是spring自带的,@Resource是JSR250规范实现的,@Inject是JSR330规范实现的,需要导入不同的包
- @Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性
- @Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
- @Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用
改变Bean作用范围的注解
-
@Scope:指定bean的作用范围,相当于以下配置:
<bean id="" class="" scope=""></bean>- 属性: value:指定范围的值,取值:singleton prototype request session globalsession
生命周期相关注解
- @PortConstruct
- @PreDestroy
相当于
<bean id="" class="" init-method="" destroy-method=""></bean>
关于XML于注解方式比较
-
注解
配置简单,维护方便(我们找到类,就相当于找到了对应的配置)
-
XML
修改时不需要改动源码,不涉及重新编译和部署
-
spring管理Bean方式比较
| XML | 注解 | |
|---|---|---|
| Bean定义 | @Component 衍生类 @Controller @Service @Repository | |
| Bean名称 | 通过id或name指定 | @Component("XXX") |
| Bean注入 | 或者p命名空间 | @Autowired 按类型注入 @Qualifier按名称注入 |
| 生命过程、 Bean作用范围 | init-method destroy-method 范围scope属性 | @PortConstruct 初始化 @PreDestroy 销毁 @Scope作用范围 |
| 适合场景 | Bean来自第三方,使用其他实现类 | Bean的实现类由用户自己开发 |
基于纯注解方式使用
-
@Configuration
-
相当于spring的XML配置文件
-
从spring3.0开始可以使用@Configuration定义配置类,可以替换XML配置文件
-
配置类内部包含由一个或者多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或者AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义对象,初始化spring容器。spring初始化时会调用配置类的无参构造函数。
-
属性:
- value:用于指定配置的字节码
-
-
@Bean
-
相当于bean标签
-
作用为:注册bean对象,主要用来配置非自定义的bean,比如DruidDataSource、SqlSessionFactory
-
@Bean标注在方法上(返回某个实例的方法)
-
属性:
- name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id),如果不指定,默认于标注的方法名相同
- @Bean注解默认作用域为单例singleton作用域,可通过@Scope("prototype")设置为对象作用域
-
-
@ComponentScan
-
相当于context:component-scan标签
-
组件扫描器,扫描@Component、@Controller、@Service、@Repository注解的类
-
该注解是编写再类上面的,一般配合@Configuration注解一起使用
-
属性
- basePackages:用于指定要扫描的包
- value:和basePackages作用一样
-
-
@PropertySource
-
相当于context:property-placeholder标签
-
编写在类上面,作用是加载properties配置文件
-
属性
- value[]:用于指定properties文件路径,如果在类路径下,需要写上classpath
-
-
@Import
-
相当于spring配置文件中的标签
-
用来组合多个配置类,在引入其他配置类时,可以不用再写@Configuration注解,若写,也无问题
-
属性
- value:用来指定其他配置类的字节码文件
-