基于注解定义BeanDefinition
1、使用注解将BeanDefinition注册到spring容器
1.1、@Component注解
@Component("car")
public class Car {
private String name;
private String price;
Get set 省略
}
以上配置等价于:
<bean id="car" class="com.wzy.web.service.Car"/>
1.2、@Service注解
@Service("car")
public class Car {
private String name;
private String price;
Get set 省略
}
以上配置等价于:
<bean id="car" class="com.wzy.web.service.Car"/>
1.3、@Repository
用于对DAO实现类进行标注,此注解上标记了@Component注解,使用
Repository有望文生义的作用
1.4、@Controller
用于对Controller进行标注。
除了@Component外其他三个注解只是为了一眼就能看出bean的真实身
份而提供的,几个注解功能都是一样的,都是往spring容器中注册bean。
1.5、component-scan注解扫描器
以上注解怎么才能被spring发现从而将标注的bean注入到容器中呢?这就
是spring提供的一个以context为命名空间的标签component-scan来决,
其中有一个属性叫base-packages属性来指定扫码那些包下面的使用注解标记 的类来注册到spring容器中,use-default-filters属性如果为true,表示默
认会对标注@Component,@Controller,@Service,@Reposity的bean进行
注册,如果为false,则自己必须且至少配置include-filter一个注解。
使用如下:
<context:component-scan base-package="com.wzy" use-default-filters=false>
<!-- base-package 如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
exclude-filter 表示com.wzy包下面除了@Controller注解,其他注解标记的bean全部注册到容器。
include-filter 表示com.wzy包下面只将@Controller标注的bean注册到容器中。
Type表示扫描类型:
annotation:该类型是采用目标类是否标记了某个注解进行过滤。
示例:com.wzy.annotation.XxxAnnotation。
assignable:该类型是采用目标类是否继承或实现了某个类进行过滤。
示例:com.wzy.XxxService
regex:表示采用正则表达式根据目标类的类名进行过滤。
示例:com\.wzy\.test\..*,表示com.wzy.test包下所有类。
custom:采用了自定义实现org.springframework.core.type.TypeFilter接口来实现过滤规则
示例:自定义的com.wzy.XxxTypeFilter。
如果在web环境中,如果容器为springMvc容器的化,需要使用注解驱动,配置如下:
<mvc:annotation-driven/>
2、使用注解装配bean
装配表示为容器中的bean 成员变量赋值),也叫依赖注入(DI)。
2.1、@Autowired标注成员变量
使用方式一:
@Autowired(required = false)
private Car car;
@Autowired 注解表示按照bean type 注入,required 默认值为true,不配置也是true。
required = true则表示必须要在spring容器中必须要能找到匹配的bean,否则会抛出
NoSushBeanDefinitionException异常。
2.2、@Qualifier配合@Autowired使用标注成员变量
因为使用@Autowired注解是按照bean的type来依赖注入的,同一中type
的bean在容器中可能会存在多个,因此就可以使用@Qualifie可以按照
bean配置的名称进行同一type的多个bean进行选择性注入。
如下案例:
<bean id="car" class="com.wzy.web.service.Car" p:name="宝马"/>
<bean id="car1" name="car2" class="com.wzy.web.service.Car" p:name="奔驰"/>
如果name没有配置的化,就会按照id选择性注入。
@Autowired
@Qualifier("car2")
private Car car;
2.3、@Autowired对方法进行标注
会将容器中的bean注入到匹配的类型参数上。
private Car car;
@Autowired
@Qualifier("car2")
private void hhhhCar(Car car){
this.car = car;
}
2.4、@Qualifier配合@Autowired对方法进行标注
private Car car;
@Autowired
private void hhhhCar( @Qualifier("car2")Car car){
this.car = car;
}
2.5、使用@Autowired对集合类型进行标注
会将容器中类型为Car的bean全部添加到集合中
@Autowired
private List<Car> carList;
会将容器中类型为Car的bean全部添加到map中,key为bean name。
@Autowired
private Map<String,Car> carMap;
而且使用@Order可以指定list、map中bean的顺序,
如下案例:
public interface Plugin {
String getName();
}
@Component
@Order(1) //order 值越小,优先被加载。
除了使用@Order 也可以使用实现Ordered接口来实现加载顺序。
public class OnePlugin implements Plugin {
public String getName() {
return "one";
}
}
@Component
@Order(2)
public class TwoPlugin implements Plugin {
public String getName() {
return "two";
}
}
@Autowired
private List<Plugin> plugins;
plugins集合中第一个元素为OnePlugin bean
plugins集合中第二个元素为TwoPlugin bean
@Autowired
private Map<String,Plugin> pluginMap;
Map也是如此顺序
2.6、@Autowired对延迟注入的支持
如果需要注入的bean是需要延迟加载的,那么使用@Autowired注入的时
候也一定要标记延迟注入。如下案例:
@Lazy
@Component("car")
public class Car {
}
@Lazy //此处@Lazy不可缺少
@Autowired(required = false) 设置required = false
private Car car;
2.7、对标准注解的支持
spring还支持JSR-250中定义的@Resource和JSR-330中的@Inject解,
这两个标准注解和@Autowired功能类似,都可以对类成员变量、方法入
参提供自动注入的功能。
@Resource 要求使用bean name进行自动注入,如果name属性不提供,则默认使用
标注的变量名称或方法的参数名称作为注入的bean name。
使用如下:
@Resource(name = "car")
private Car car;
标注函数
private Car car;
@Resource(name = "car")
private void hhhhCar(Car car){
this.car = car;
}
@Inject 和@Autowired一样都是按照bean的type来自动注入,只是没有required属性。
2.8、@Scope
bean的作用域的注解,使用如下:
@Component
@Scope(value = "prototype")
public class Car {
}
2.9、 @PostConstruct
@PostConstruct表示bean 的初始化生命周期,标注对象为bean的函
数,相当于bean标签的init-method,一个bean可以标注多个函数。
2.10、@PreDestroy
@PreDestroy表示bean的销毁生命周期,标注对象也是bean的函数,相
当于bean标签的destory-method,一个bean也可以标注多个函数。
使用案例如下:
@Component
public class Car {
public Car() {
System.out.println("Construct method...");
}
@Autowired
private void handlerBoss(Boss boss){
System.out.println("inject boss...");
}
@PostConstruct
private void init1(){System.out.println("初始化方法1..."); }
@PostConstruct
private void init2(){System.out.println("初始化方法2...");}
@PreDestroy
private void destroy1(){System.out.println("销毁方法1...");}
@PreDestroy
private void destroy2(){ System.out.println("销毁方法2...");}
}
加载容器的时候输出如下:
Construct method... 1、调用构造函数实例化bean
inject boss... 2、自动注入
初始化方法1... 3、调用初始化函数
初始化方法2...
关闭容器输出
销毁方法1... 4、容器关闭的时候调用销毁bean函数
销毁方法2...
以上输出说明spring的执行流程是按上面4个步骤依次往下执行。