zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    PHP应用目录结构设计
    php 项目性能优化
    Zend Framework的PHP编码规范【1】
    php 如何做在线人数统计
    linux 文件权限
    总结:常用的通用数据处理指令
    全排列(含递归和非递归的解法)
    局部变量,静态局部变量,全局变量,静态全局变量在内存中的存放区别(转)
    C++中引用详解
    Pascal三角形
  • 原文地址:https://www.cnblogs.com/ic710/p/11027169.html
Copyright © 2011-2022 走看看