SpringBoot之@Bean
@Bean注解用于声明一个方法,它会返回一个由Spring管理的Bean实例(对象)。
默认情况下,当容器启动时就该函数就会被执行,但当该函数同时被@Lazy注释时,则只有第一次被用到时,才会执行。
另外,由@Bean注解生成时的Bean是单例模式。
定义
// 对象类:为了测试,简单点
@Data
public class AppService {private String id;private String appId;
}// 配置类
@Configuration
public class MyConfig{@Beanpublic AppService createAppServiceBean(){System.out.println("@Bean执行了");AppService entity = new AppService();entity.setId("bean");return entity;}
}
从截图中可以看出,当程序被启动时,方法已经被执行了。
使用
// 使用
@RestController
@RequestMapping("/test")
public class TestController {@Resourceprivate 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方法。执行如截图: