Spring_2
Bean的定义及作用域的注解实现-------
转载请注明出处:http://www.cnblogs.com/JsonShare
Bean管理的注解实现
- Classpath扫描与组件管理
- 类的自动检测与注册Bean
- <context:annotation-config/>
- @Component,@Repository,@Service,@Controller
以下单独讲解:
- @Required
- @Autowired
- @Qualifier
- @Resource
(一) Classpath扫描与组件管理
- 从Spring3.0开始,Spring javaConfig项目提供了很多特性,包括使用java而不是xml定义bean,比如:@Configuration,@Bean,@Import,@DependsOn
- @Component是一个通用的注解,可用于任何的bean
- @Repository,@Service,@Controller是更有针对性的注解
- @Repository 通常用于注解DAO类,即持久层
- @Service 通常用于注解 Service类,即服务层
- @Controller 通常用于注解Controller类,即控制层
- @Component是所有受Spring管理组件的通用形式,Spring还提供了更加细化的注解形式:@Repository、@Service、@Controller,它们分别对应持久层Bean,服务层Bean,和控制层Bean。这些注解与@Component的语义是一样的,完全通用,为了给它们追加更多的语义。所以,推荐使用@Repository、@Service、@Controller来替代@Component。
(二) 类的自动检测及Bean的注册
Spring可以自动检测类并注册Bean到ApplicationContext中
(三) <context:annotation-config/>
- 通常在基于XML的Spring配置如下标签(请注意包含上下文命名空间)
- <context:annotation-config/>仅会查找在同一个applicationContext中的bean注解
1
2
3
4
5
6
7
8
9
10
11
|
<?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/beans http: //www.springframework.org/schema/beans/spring-beans-4.1.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:annotation-config/> <beans/> |
(四)类的自动检测及Bean的注册(补充)
为了能够检测这些类并注册相应的bean,需要下面的内容:
<context:component-scan>中包含有
<context:annotation-config/>,使用前者后不再使用后者
1
2
3
4
5
6
7
8
9
10
11
|
<?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/beans http: //www.springframework.org/schema/beans/spring-beans-4.1.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:component-scan base- package = "com.mypackage" ></context:component-scan> </beans> |
该配置隐式注册了多个对注解进行解析的处理器,如:
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
其实,注解本身做不了任何事情,和XML一样,只起到配置的作用,主要在于背后强大的处理器,其中就包括了<context:annotation-config/>配置项里面的注解所使用的处理器,所以配置了<context:component-scan base-package="">之后,便无需再配置<context:annotation-config>
(五)使用过滤器进行自定义扫描
- 默认情况下,类被自动发现并注册bean的条件是:使用@Component,@Repository,@Service,@Controller注解或者使用@Component的自定义注解
- 可以通过过滤器修改上面的行为,如:下面例子的xml配置忽略所有的@Repository注解并用“Stub”代替
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?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/beans http: //www.springframework.org/schema/beans/spring-beans-4.1.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:component-scan base- package = "com.mypackage" > <!-- 包含的过滤器 --> <context:include-filter type= "regex" expression= ".*Stub.*Repository" /> <!-- 排除的过滤器 --> <context:exclude-filter type= "annotation" expression= "org.springframework.stereotype.Repository" /> </context:component-scan> </beans> |
- 还可以使用use-default-filters="false" 禁用自动发现并注册
(六)定义Bean
扫描过程中组件被自动检测,那么Bean名称事由BeanNameGenerator生成的(@Component,@Repository,@Service,@Controller都会有个name属性用于显式设置Bean Name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Component ( "exampleBean" ) public class ExampleBean{ //........ } ------------------------------ @Service ( "exampleBean" ) public class ExampleBean{ //........ } ------------------------------ //虽然并未显式声明,但会根据BeanNameGenerator自动生成,规则:以类名为基础,类名第一个字母小写 @Repository public class ExampleBean{ //........ } |
可自定义bean命名策略,实现BeanNameGenerator接口,并一定要包含一个无参构造器
1
2
3
4
|
<!-- 自定义的命名规则,例如: 类名全小写,全大写.....;按照自己的方式实现--> <context:component-scan base- package = "com.mypackage" name-generator= "com.mypackage.MyBeanNameGenerator" > </context:component-scan> |
(七)作用域
通常情况下自动查找的Spring组件,其Scope是singleton,Spring提供了一个标识scope的注解@Scope
1
2
3
4
5
|
@Scope ( "prototype" ) @Repository public class OneInterfaceImpl extends OneInterface { //.......... } |
也可以自定义scope策略,实现ScopeMetadataResolver接口,并提供一个无参的构造器
1
2
|
<context:component-scan base- package = "com.mypackage" scope-resolver= "com.mypackage.MyScopeMetadataResolver" > </context:component-scan> |
(八)代理方式
可以使用scope-proxy属性指定代理,有三个值可选:no,interfaces,targetClass
1
2
|
<context:component-scan base- package = "com.mypackage" scoped-proxy= "interfaces" ><br> </context:component-scan> |
蓝色字体:具体的设置方式参照spring的配置文档说明
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" >
<context:component-scan base-package="com.imooc.beanannotation"></context:component-scan>
</beans>
//@Component("bean")
@Scope //默认是(singleton)
@Component
public class BeanAnnotation {
public void say(String arg) {
System.out.println("BeanAnnotation : " + arg);
}
public void myHashCode() {
System.out.println("BeanAnnotation : " + this.hashCode());
}
}
@RunWith(BlockJUnit4ClassRunner.class)
public class TestBeanAnnotation extends UnitTestBase {
public TestBeanAnnotation() {
super("classpath*:spring-beanannotation.xml");
}
@Test
public void testSay() {
BeanAnnotation bean = super.getBean("beanAnnotation");
bean.say("This is test.");
bean = super.getBean("bean");
bean.say("This is test.");
}
@Test
public void testScpoe() {
BeanAnnotation bean = super.getBean("beanAnnotation");
bean.myHashCode();
bean = super.getBean("beanAnnotation");
bean.myHashCode();
}
}
=======================
@Required注解是用于bean属性的setter方法
这个注解仅仅表示,受影响的bean属性必须在配置时被填充,通过在bean定义胡通过自动装配一个明确的属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package com.mypackage; import org.springframework.beans.factory.annotation.Required; public class SimpleMovieLister { private MovieFinder movieFinder; @Required public void setMovieFinder(MovieFinder movieFinder) { this .movieFinder = movieFinder; } //..... } |
PS:这样如果任何带有@Required的属性未设置的话 将会抛出BeanInitializationException异常