@Bean注解用于声明一个方法,它会返回一个由Spring管理的Bean实例(对象)。
默认情况下,当容器启动时就该函数就会被执行,但当该函数同时被@Lazy注释时,则只有第一次被用到时,才会执行。
另外,由@Bean注解生成时的Bean是单例模式。
定义
// 对象类:为了测试,简单点
@Data
public class AppService {
private String id;
private String appId;
}
// 配置类
@Configuration
public class MyConfig{
@Bean
public AppService createAppServiceBean(){
System.out.println("@Bean执行了");
AppService entity = new AppService();
entity.setId("bean");
return entity;
}
}
从截图中可以看出,当程序被启动时,方法已经被执行了。
使用
// 使用
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private AppService entity;
/**
* 测试注解@Bean
* 在被@Configuration修饰的类中,通过@Bean注解生成Bean,这个bean会被spring管理,当通过自动注入时
* 会直接使用该bean。
* @return
*/
@GetMapping("/bean")
public Response testBean(){
Response resp = new Response();
entity.setAppId("update");
resp.setData(entity);
return resp;
}
/**
* 由此方法可以表名,对于@bean创建的对象是全局的,当1修改后,2访问的也是修改后的
* @return
*/
@GetMapping("/bean2")
public Response testBean2(){
Response resp = new Response();
resp.setData(entity);
return resp;
}
/**
* 通过new创建对象测试是否返回@Bean创建的对象
* @return
*/
@GetMapping("/bean3")
public Response testBean3(){
AppService testEntity = new AppService();
Response resp = new Response();
resp.setData(testEntity);
return resp;
}
}
三个接口的执行结果为:
使用总结
从三张截图,我们可以得到以下结论:
- 从截图1,截图2中能看到,当接口1改变了Bean对象中的AppId时,接口2的返回值也发生了改变。所以,@Bean创建的对象是单例。
- 从截图3中可看到,通过new创建的对象没有得到@Bean创建的对象的注入。所以返回值的id为null。因此,@Bean创建的对象仅对自动注入生效。
初始化执行
咱们来改造一下AppService.class
@Data
public class AppService {
private String id;
private String appId;
public void start(){
System.out.println("@Bean start");
}
public void destroy(){
System.out.println("@Bean destroy");
}
}
再来改造一下config类
@Configuration
public class MyConfig{
// 注意,此处是重点
@Bean(initMethod="start", destroyMethod="destroy")
public AppService createAppServiceBean(){
System.out.println("@Bean执行了");
AppService entity = new AppService();
entity.setId("bean");
return entity;
}
}
接下来,咱们说明一下。是当对象初始完成后,会执行initMethod属性执行的方法,即AppService类中的start方法。当程序结束时,会执行destroyMethod属性指向的方法,即AppService类的destroy方法。执行如截图: