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"/>

相关文章
相关标签/搜索