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 }

 

posted @ 2019-06-15 12:15  知识航海家布尔  阅读(352)  评论(0编辑  收藏  举报