在简单介绍了一下如何声明一个Bean组件,并将其交给Spring进行管理之后,下面我们来介绍一下Spring 的基本构成
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interface Bean {
@AliasFor("name")
String[] value() default {};
@AliasFor("value")
String[] name() default {};
Autowire autowire()default Autowire.NO;
String initMethod()default"";
String destroyMethod()default AbstractBeanDefinition.INFER_METHOD;
}
@Bean不仅可以作用在方法上,也可以作用在注解类型上,在运行时提供注册。
value: name属性的别名,在不需要其他属性时使用,也就是说value 就是默认值
name: 此bean 的名称,或多个名称,主要的bean的名称加别名。如果未指定,则bean的名称是带注解方法的名称。如果指定了,方法的名称就会忽略,如果没有其他属性声明的话,bean的名称和别名可能通过value属性配置
autowire : 此注解的方法表示自动装配的类型,返回一个Autowire类型的枚举,我们来看一下Autowire枚举类型的概念
// 枚举确定自动装配状态:即,bean是否应该使用setter注入由Spring容器自动注入其依赖项。// 这是Spring DI的核心概念publicenumAutowire {
// 常量,表示根本没有自动装配。
NO(AutowireCapableBeanFactory.AUTOWIRE_NO),
// 常量,通过名称进行自动装配
BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),
// 常量,通过类型进行自动装配
BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
privatefinalint value;
Autowire(int value) {
this.value = value;
}
publicintvalue() {
returnthis.value;
}
publicbooleanisAutowire() {
return (this == BY_NAME || this == BY_TYPE);
}
}
autowire的默认值为No,默认表示不通过自动装配。
initMethod: 这个可选择的方法在bean实例化的时候调用,InitializationBean接口允许bean在合适的时机通过设置注解的初始化属性从而调用初始化方法,InitializationBean 接口有一个定义好的初始化方法
voidafterPropertiesSet()throws Exception;
Spring不推荐使用InitializationBean 来调用其初始化方法,因为它不必要地将代码耦合到Spring。Spring推荐使用@PostConstruct注解或者为POJO类指定其初始化方法这两种方式来完成初始化。
不推荐使用:
publicclassInitBeanimplementsInitializingBean {
publicvoidafterPropertiesSet() {}
}
destroyMethod: 方法的可选择名称在调用bean示例在关闭上下文的时候,例如JDBC的close()方法,或者SqlSession的close()方法。DisposableBean 接口的实现允许在bean销毁的时候进行回调调用,DisposableBean 接口之后一个单个的方法
voiddestroy()throws Exception;
Spring不推荐使用DisposableBean 的方式来初始化其方法,因为它会将不必要的代码耦合到Spring。作为替代性的建议,Spring 推荐使用@PreDestory注解或者为@Bean注解提供 destroyMethod 属性,
不推荐使用:
publicclassDestroyBean {
publicvoidcleanup() {}
}
推荐使用:
publicclassMyBean {
publicMyBean(){
System.out.println("MyBean Initializing");
}
publicvoidinit(){
System.out.println("Bean 初始化方法被调用");
}
publicvoiddestroy(){
System.out.println("Bean 销毁方法被调用");
}
}
@ConfigurationpublicclassAppConfig {
// @Bean@Bean(initMethod = "init", destroyMethod = "destroy")public MyBean myBean(){
returnnewMyBean();
}
}
修改一下测试类,测试其初始化方法和销毁方法在何时会被调用
publicclassSpringBeanApplicationTests {
publicstaticvoidmain(String[] args) {
// ------------------------------ 测试一 ------------------------------ApplicationContextcontext=newAnnotationConfigApplicationContext(AppConfig.class);
// context.getBean("myBean");
// 变体
context.getBean("myBean");
((AnnotationConfigApplicationContext) context).destroy();
// ((AnnotationConfigApplicationContext) context).close();
}
}
初始化方法在得到Bean的实例的时候就会被调用,销毁方法在容器销毁或者容器关闭的时候会被调用。