從Spring3.0,@Configuration用於定義配置類,可替換xml配置文件,被註解的類內部包含有一個或多個被@Bean註解的方法,這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進行掃描,並用於構建bean定義,初始化Spring容器。spring
@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
@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); } }
能夠使用基於 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;
@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(); } }
@Configuation等價於<Beans></Beans>
@Bean等價於<Bean></Bean>
@ComponentScan等價於<context:component-scan base-package="com.lemon.bean"/>