@Bean
@Bean标识一个用于配置和初始化一个由SpringIOC容器管理的新对象的方法,也就是说通过@Bean可以生成一个IOC容器的bean实例,类似于XML配置文件的<bean/>
。
可以在Spring的@Component注解的类,然后在类中使用@Bean注解任何方法(仅仅是可以),然后在方法中去创建对象,进行返回。
上一点中,通常使用的是@Configuration和@Bean配合使用。
例如:
@Configuration
public class AppConfig{
@Bean
public MyService myService(){
return new MyServiceImpl();
}
}
在AppConfig这个类上用了@Configuration,就相当于AppConfig这个类就是一个配置文件。然后里边有一个方法返回的是一个MyService类型,方法内部创建了对象并返回,这个方法用@Bean注解。这个方法用Bean注解,相当于创建了一个bean,id是myService,class对应MyServiceImpl,也就是创建了MyService接口MyServiceImpl的实现类的对象。
也就是
<beans><bean id="myService" class="com.services.MyServiceImpl"></beans>
这两段的起到的效果是一样的,都是在Spring的IOC容器中添加一个对象。不过第一种是使用编码加注解的方式,第二种是基于XML配置文件的方式。
自定义Bean name,init-method,destroy-method
@Configuration
public class AppConfig{
@Bean(name="myFoo")
public Foo foo(){
return new Foo();
}
}
这里@Bean(name=”myFoo”)指定bean的name,就相当于xml文件中写的bean的id。
同时还支持init-method和destroy-method,这个和之前说到的bean的生命周期里的初始化和销毁方法是一样的。
比如在类Foo中有init()方法,在类Bar里有destroy()方法,@Bean下的方法中return new Foo();,可以写@Bean(initMethod=”init”),另一个销毁方法同理。要注意的是,那个初始化方法和销毁方法是return中的那个,也就是new的实现类。
看个例子:
定义接口Store和实现类StringStore,里边有初始化方法和销毁方法。
public interface Store {}
public class StringStore implements Store {
public void init() {
System.out.println("This is init.");
}
public void destroy() {
System.out.println("This is destroy.");
}
}
定义一个类StoreConfig并使用@Configuration来注解
@Configuration
public class StoreConfig {
@Bean
public Store getStringStore(){
return new StringStore();
}
}
在单元测试类中要想获取bean,肯定要知道bean的id是什么,是前边的store(Store首字母小写)还是stringStore(StringStore首字母小写),都不是。
如果使用@Bean这个注解,在没有指定name的时候,那么Bean的name是方法名,所以这里应该是getStringStore。不过以getStringStore作为bean的名称不太合适,所以稍微修改为stringStore。
@Configuration
public class StoreConfig {
@Bean
public Store stringStore(){
return new StringStore();
}
}
单元测试类中为
@Test
public void test() {
Store store = super.getBean("stringStore");
System.out.println(store.getClass().getName());
}
输出为com.imooc.beanannotation.javabased.StringStore
因为方法返回的是StringStore()。
如果指定了名称,那么getBean中的参数就不是方法名,而是指定的那个名称。
还可以指定initMethod和destroyMethod,这两个方法在实现类中,这样单元测试类中测试是会先执行initMethod,然后结束时会执行destroyMethod。
@Bean(name = "stringStore", initMethod="init", destroyMethod="destroy")
public Store stringStore() {
return new StringStore();
}