Spring註解編程(二)---@Configuration&@Bean

從Spring3.0,@Configuration用於定義配置類,可替換xml配置文件,被註解的類內部包含有一個或多個被@Bean註解的方法,這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進行掃描,並用於構建bean定義,初始化Spring容器。spring

1.@Configuration的定義

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

   /**
    * Explicitly specify the name of the Spring bean definition associated
    * with this Configuration class. If left unspecified (the common case),
    * a bean name will be automatically generated.
    * <p>The custom name applies only if the Configuration class is picked up via
    * component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.
    * If the Configuration class is registered as a traditional XML bean definition,
    * the name/id of the bean element will take precedence.
    * @return the specified bean name, if any
    * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
    */
   String value() default "";

}

注意:@Configuration註解的配置類有以下要求:app

@Configuration不能夠是final類型;
@Configuration不能夠是匿名類;
嵌套的configuration必須是靜態類。ide

2.@Configuation+@Bean註冊Bean

@Configuration標註在類上,至關於把該類做爲spring的xml配置文件中的<beans>,做用爲:配置spring容器(應用上下文)post

//配置類==配置文件
@Configuration  //告訴Spring這是一個配置類
public class MainConfig {

   //給容器中註冊一個Bean;類型爲返回值的類型,id默認是用方法名做爲id
   @Bean
   public Person person(){
      return new Person("lisi", 20);
   }

}

主方法進行測試:測試

public class MainTest {
   
   @SuppressWarnings("resource")
   public static void main(String[] args) {
      ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
      Person bean = applicationContext.getBean(Person.class);
      System.out.println(bean);
   
   }

}

@Bean下管理bean的生命週期

能夠使用基於 Java 的配置來管理 bean 的生命週期。this

1)@Bean 支持兩種屬性,即 initMethod 和destroyMethod,這些屬性可用於定義生命週期方法。在實例化 bean 或即將銷燬它時,容器即可調用生命週期方法。生命週期方法也稱爲回調方法,由於它將由容器調用。spa

@Configuration
public class MainConfigOfLifeCycle {
   
   //@Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}
public class Car {
   
   public Car(){
      System.out.println("car constructor...");
   }
   
   public void init(){
      System.out.println("car ... init...");
   }
   
   public void detory(){
      System.out.println("car ... detory...");
   }

}

2)經過讓Bean實現InitializingBean(定義初始化邏輯),DisposableBean(定義銷燬邏輯);prototype

@Component
public class Cat implements InitializingBean,DisposableBean {

   public Cat(){
      System.out.println("cat constructor...");
   }

   //銷燬方法
   public void destroy() throws Exception {
      // TODO Auto-generated method stub
      System.out.println("cat...destroy...");
   }

   // 初始化方法
   public void afterPropertiesSet() throws Exception {
      // TODO Auto-generated method stub
      System.out.println("cat...afterPropertiesSet...");
   }

}

 3)@Bean 註釋註冊的 bean 也支持 JSR-250 規定的標準 @PostConstruct 和 @PreDestroy 註釋。code

@PostConstruct    在bean建立完成而且屬性賦值完成;來執行初始化方法component

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

@PreDestroy:在容器銷燬bean以前通知咱們進行清理工做

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@Component
public class Dog {


   public Dog(){
      System.out.println("dog constructor...");
   }

   //對象建立並賦值以後調用
   @PostConstruct
   public void init(){
      System.out.println("Dog....@PostConstruct...");
   }

   //容器移除對象以前
   @PreDestroy
   public void detory(){
      System.out.println("Dog....@PreDestroy...");
   }

}

4)bean的後置處理器:實現BeanPostProcessor接口是在bean初始化先後進行一些處理工做,返回值是即將用到的bean,能夠是原來的bean也能夠是包裝後的bean

public interface BeanPostProcessor {
    //在初始化以前工做
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
    //在初始化以後工做
    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

示例

/**
 * 後置處理器:初始化先後進行處理工做
 * 將後置處理器加入到容器中
 * @author lpf
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      // TODO Auto-generated method stub
      System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
      return bean;
   }

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      // TODO Auto-generated method stub
      System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
      return bean;
   }

}
    * BeanPostProcessor原理
    * populateBean(beanName, mbd, instanceWrapper);給bean進行屬性賦值
    * initializeBean
    * {
    * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    * invokeInitMethods(beanName, wrappedBean, mbd);執行自定義初始化
    * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    *}
* Spring底層對 BeanPostProcessor 的使用;
* 咱們最熟悉的XXXAware接口 就是經過ApplicationContextAwareProcessor後置處理器來實現的
* 還有bean賦值,注入其餘組件,@Autowired,生命週期註解功能,@Async,xxx BeanPostProcessor;

 

3.@Configuration啓動容器+@Component註冊Bean

@Component
public class Car {
   
   public Car(){
      System.out.println("car constructor...");
   }
   
   public void init(){
      System.out.println("car ... init...");
   }
   
   public void detory(){
      System.out.println("car ... detory...");
   }

}

配置類

//添加自動掃描註解,basePackages爲Car包路徑
@ComponentScan("com.lemon.bean")
@Configuration
public class MainConfigOfLifeCycle {

   @Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}

4.@Configuation總結


     @Configuation等價於<Beans></Beans>

     @Bean等價於<Bean></Bean>

     @ComponentScan等價於<context:component-scan base-package="com.lemon.bean"/>

相關文章
相關標籤/搜索