Spring学习(三)Spring Bean装配(常用注解)
注册与管理Bean
=======================================
·从 Spring3.0开始, Spring Java Config项目提供了很多特性包括使用ava而不是XML定义bean,比如
@ Configuration, @Bean, @Import, @Dependson
·@ Componenti是一个通用注解,可用于任何bean
·@ Repository,@ Service,@ Controller是更有针对性的注解
-@ Repository通常用于注解DAO类,即持久层
-@ Servicei通常用于注解 Service类,即服务层
-@ Controller通常用于 Controller类,即控制层(MVC)
元注解(Meta-annotations)
======================================
·许多 Spring提供的注解可以作为自己的代码,即“元数据注解元注解是一个简单的注解,可以应用到另ー个注解
·
类的自动检测及Bean的注册
=====================================
·Spring可以自动检测类并注册Bean到 Application Context中
如:@Service @Repository @Autovired
<context:annotation-config/>
·通过在基于XML的 Spring配置如下标签(请注意包含上下文命名空间)
·< context: annotation- config/>仅会查找在同一个application Context中的bean注解
<beans xmlns="..."> <context:annotation-config/> </beans>
<beans xmlns="..."> <context:component-scan base-package="com.demo"/> </beans>
·< context:: component-scan>包含< context: annotationconfig>,通常在使用前者后,不用再使用后者
· AutowiredannotationBeanPostprocessor和Commonannotation Bean Postprocessor也会被包含进来
使用过滤器进行自定义扫描
=================================
·默认情况下,类被自动发现并注册bean的条件是:使用@Component, @Repository, @Service, @Controller 注解或者使用 @Component的自定义注解
·可以通过过器修改上面的行为,如:下面例子的XML配置忽略所有的@ Repositoryi注解并用"Stub"代替
<beans> <context:component-scan base-package="com.demo"> <context:include-filter type="regex" expression=".*Stub.*Repository"/> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> </beans>
定义Bean
=================================
·扫描过程中组件被自动检测,那么Bean名称是由Beannamegenerator生成的(@ Component,@ Repository,@ Service,@ Controller都会有个name属性用于显式设置 Bean Name)
1 @Service("Mydemo") 2 public class Demo{} 3 //在不使用自定义BeanID时,会自动类第一个字母小写当ID demo 4 @Service 5 public class Demo{}
·可自定义bean命名策略,实现 Beannamegenerator接口并一定要包含一个无参数构造函器
<beans> <context:component-scan base-package="com.demo" name-generator="com.demo.MyDemo" /> </beans>
作用域(Scope)
==================================
·通常情况下自动查找的 Spring组件,其 scope是 E singletonSpring2.5提供了ー个标识 scope的注解@ Scope
1 @Scope("prototype") 2 @Repository 3 public class Demo{}
·也可以自定义 scope策陥,实现 Scopemetadata Resolverf接口并提供一个无参构造器
<beans> <context:component-scan base-package="com.demo" scope-resolver="com.demo.Mydemo" /> </beans>
代理方式
=====================================
可以使用 scoped-proxy属性指定代理,有三个值可选:no, interfaces, targetClass
<beans> <context:component-scan base-package="com.demo" scope-proxy="interfaces" /> </beans>
@Required
=====================================
·@ Required注解适用于bean属性的 setter方法
·这个注解仅仅表示,受影响的bean属性必须在配置时被填充通过在bean定义就通过自动装配一个明确的属性值
public class Demo{ private Lizhi lizhi; @Required public void setLizhi(Lizhi lizhi){ this.lizhi = lizhi; } }
@ Autowired
======================
·可以将@ Autowiredi注解为“传统”的 setter方法
1 public class Demo{ 2 private Lizhi lizhi; 3 4 @Required 5 public void setLizhi(Lizhi lizhi){ 6 this.lizhi = lizhi; 7 } 8 }
·可用于构造器或成员变量
1 @Autovired 2 private Lizhi lizhi; 3 private LizhiDao lizhiDao; 4 @Autovired 5 public LizhiFan(LizhiDao lizhiDao){ 6 this.lizhiDao = lizhiDao; 7 }
·默认情况下,如果因找不到合适的bean将会导致 autowiring失败抛出异常,可以通过下面的方式避兔
1 public class SimpleDemo{ 2 private Demo demo; 3 4 @Autowired(required=false) 5 public void setDemo(Demo demo){ 6 this.demo = demo; 7 } 8 }
·每个类只能有一个构道器被标记为 required=true
· @Autowired的必要属性,建议使用@Required注解
·可以使用@Autowiredi注解那些众所周知的解析依赖性接口,比如: Beanfactory, Applicationcontext, Environment,Resourceloader, Applicationeventpublisher, andMessagesource
@Qualifier
==============================
·按类型自动装配可能多个bean实例的情况,可以使用 Spring的@Qualifier注解缩小范围(或指定睢一),也可以用于指定单独的构造器参数或方法参数
·可用于注解集合类型变量
1 //例子一 2 public class Demo{ 3 @Autovired 4 @Qualifier("main") 5 private Demo demo; 6 } 7 //例子二 8 public class Demo{ 9 private Demo demo; 10 private DemoDao demoDao; 11 12 @Autovied 13 public void prepare(@Qualifier("main")Demo demo, DemoDao demoDao){ 14 this.demo = demo; 15 this.demoDao = demoDao; 16 } 17 .... 18 }
1 <beans xmlns="..."> 2 <context:annotation-config/> 3 <bean class="com.Demo"> 4 <qualifier value="main"/> 5 </bean> 6 <bean class="com.Demo"> 7 <qualifier value="action"/> 8 </bean> 9 </beans>
·如果通过名字进行注解注入,主要使用的不是@ Autowired(即使在技术上能够通过@ Qualifier指定bean的名字),替代方式是使用SR-250@ Resource注解,它是通过其独特的名称来定义来识別特定的目标(这是一个与所声明的类型是无关的匹配过程)
·因语义差异,集合或Map类型的bean无法通过@ Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@ Resource注解,通过唯一名称引用集合或Map的bean
·@Autowired适用于 fields, constructors, multi- argumentmethods这些允许在参数级别使用@Qualifier注解缩小范围的情况
·@Resourcei适用于成员变量、只有ー个参数的 setter方法,所以在目标是构造器或一个多参数方法时,最好的方式是使用qualifiers
·定义自己的qualifier注解并使用
1 //例子一 2 @Target({ElementType.FIELD, ElementType.PARAMETER}) 3 @Retention(RetentionPolicy.RUNTIME) 4 @Qualifier 5 public @interface Genre{ 6 String value(); 7 } 8 //例子二 9 public class DemoMain{ 10 @Autovired 11 @Genre("Action") 12 private Demo demo1; 13 private Demo demo2; 14 15 @Autovired 16 public void setDemo(@Genre("Comedy") Demo demo){ 17 this.this.demo2 = demo; 18 } 19 ... 20 }
·自定义
1 <beans xmlns="..."> 2 <context:annotation-config/> 3 <bean class="com.DemoMian"> 4 <qualifier type="Genre" value="Action" /> 5 </bean> 6 <bean class="com.DemoMian"> 7 <qualifier type="example.Genre" value="Comedy" /> 8 </bean> 9 </beans>
基于java的容器注解
@Bean
====================================
·@Bean标识一个用于配置和初始化一个由 Springloc容器管理的新对象的方法,类似于XML配置文件的<bean/>
·可以在 Spring的@ Componenti注解的类中使用@Bean注解任何方法(仅仅是可以)
・上一点中,通常使用的是@ Configuration
1 @Configuration 2 public class Demo{ 3 @Bean 4 public MyService myservice(){ 5 return new MyServiceImpl(); 6 } 7 }
<beans> <bean id="myService" class="com.demo.MyServiceImpl" /> </beans>
·自定义Bean name
1 @Configuration 2 public class DemoMain{ 3 @Bean(name="myDemo") 4 public Demo demo(){ 5 return new Demo(); 6 } 7 }
·init-method
·destroy-method
1 public class DemoF{ 2 public void init(){} 3 } 4 public class DemoB{ 5 public void cleanup(){} 6 } 7 8 @Configuration 9 public class DemoMain{ 10 @Bean(initMethod = "init") 11 public DemoF demof(){ 12 return new DemoF; 13 } 14 @Bean(destroyMethod = "cleanup") 15 public DemoB demob(){ 16 return new DemoB; 17 } 18 }
使用@ImportResource和@Value注解进行资源文件读取。
================================================
xml方式:
1 <beans> 2 <context:annotation-config/> 3 <context:property-placeholder location="classpath:/com/demo/jdbc.properties"/> 4 <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 5 <property name="url" value="${jdbc.url}" /> 6 <property name="username" value="${jdbc.username}" /> 7 <property name="password" value="${jdbc.password}" /> 8 </bean> 9 </beans>
注解方式:
1 @Configuration 2 @ImportResource("classpath:/com/demo/properties-config.xml") 3 public class Demo{ 4 @Value("${jdbc.url}") 5 private String url; 6 @Value("${jdbc.username}") 7 private String username; 8 @Value("${jdbc.password}") 9 private String password; 10 11 @Bean 12 public DataSource dataSource(){ 13 return new DriverManagerDataSource(url, username, password); 14 } 15 }
@Bean and @Scope
===========================================
·默认@Bean是单例的
Bean的作用域包括singleton、prototype、request、session、global session
1 //例一 2 @Configuration 3 public class MyDemo{ 4 @Bean 5 @Scope("prototype") 6 public Demo demo(){ 7 ... 8 } 9 } 10 11 //例二 12 @Bean 13 @Scope(value="session", proxyMode= ScopeProxyMode.TARGET_CLASS) 14 public Demo demo(){ 15 return new Demo(); 16 } 17 18 @Bean 19 public Service myService(){ 20 Service myService = new Service(); 21 service.setService(demo()); 22 return service; 23 }
基于泛型的自动装配
=============================
1 @Configuration 2 public class Demo { 3 @Bean 4 public StringDemo stringDemo(){ 5 return new StringDemo; 6 } 7 8 @Bean 9 public IntegerDemo stringDemo(){ 10 return new IntegerDemo; 11 } 12 } 13 //示例 14 @Autowired 15 private Demo<String> demo1; 16 @Autowired 17 private Demo<Integer> demo2; 18 19 //示例 20 @Autowired 21 private List<Demo<Integer>> lists;
CustomAutowireConfigurer
========================================
·Customautowire Configurer=Beanfactorypostprocessor的子类,通过它可以注册自己的qualifier注解类型(即使没有使用 Spring的@ Qualifier注解)
1 <bean id="customAutowireCOnfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> 2 <property name="customQualifierTypes"> 3 <value>com.Demo</value> 4 </property> 5 </bean>
·该 Autowire Candidate Resolver决定自动装配的候选者:
-每个bean定义的 autowire- candidate值
-任何<bean/>中的 default- autowire- candidates
-@Qualifier注解及使用 Customautowire Configurer的自定义类型
@Rrsource
========================================
·Spring还支持使用JSR-250@ Resource注解的变量或 setter方法,这是一种在 Java EE5和6的通用模式, Spring管理的对象也支持这种模式
·@ Resources有一个name属性,并且默认 Spring解释该值作为被注入bean的名称
1 public class Demo{ 2 private UserDemo userDemo; 3 4 @Resource(name="myUser") 5 public void setUserDemo(UserDemo userDemo){ 6 this.userDemo = userDemo; 7 } 8 }
@PostConstruct and @PreDestroy
===========================================
・ CommonAnnotationBeanPostProcessor不仅能识别JSR250中的生命周期注解@ Resource,在 Spring2.5中引入支持初始化回调和销毁回调,前提是CommonAnnotationBeanPostProcessor是Spring的Application Contextl中注册的
1 public class CachingMoviceLister { 2 3 @PostConstruct 4 public void populateMovieCache(){} 5 6 @PreDestroy 7 public void clearMovieCache(){} 8 }
使用JSR330标准注解
===========================================
·从 Spring3.0开始支持JSR330标准注解依赖注入注解),其扫描方式与 Spring注解一致
·使用R330需要依赖 avaxInjec包
·使用 Maven引入方式
1 <dependency> 2 <groupId>javax.inject</groupId> 3 <artifactId>javax.inject</artifactId> 4 <version>1</version> 5 </dependency>
@Injec
===========================================
@Iject等效于@Autowired,可以使用于类、属性、方法、构造器
public class Demo { public UserDemo userDemo; @Inject public void setUserDemo(UserDemo userDemo){ this.userDemo = userDemo; } }
@Named
===========================================
·如果想使用特定名称进行依赖注入,使用@ Named@ Named与@ Component是等效的
1 //示例一 2 public class Demo { 3 4 public UserDemo userDemo; 5 6 @Inject 7 public void setUserDemo(@Named("main")UserDemo userDemo){ 8 this.userDemo = userDemo; 9 } 10 } 11 //示例二 12 @Named("demo") 13 public class Demo { 14 15 public UserDemo userDemo; 16 17 @Inject 18 public void setUserDemo(UserDemo userDemo){ 19 this.userDemo = userDemo; 20 } 21 }