SpringBoot Bean的注入
一、使用@configuration
可以理解为是spring的xml文件的beans部分定义。
a)如何定义?
- 在类中加入@Configuration注解
- 在方法加入@Bean注解完成bean的定义,也可以使用name指定bean注册的名称,默认为方法名。
b)如何使用?
- 使用@Autowired注解注入或构造函数注入
1 @Configuration 2 public class ServicePriceConfiguration { 3 /** 4 * 显式指定bean的名称 5 * @return 6 */ 7 @Bean(name = "priceBean") 8 PriceService initPriceBean() { 9 return new PriceServiceImpl(); 10 } 11 12 /** 13 * 初始化productbean 14 * @return 15 */ 16 @Bean 17 ProductService initProductBean() { 18 return new ProductServiceImpl(); 19 } 20 21 /** 22 * 初始化shoppingcar bean 23 * @return 24 */ 25 @Bean 26 ShoppingCarService initCarBean() { 27 return new ShoppingCarServiceImpl(); 28 } 29 }
bean的使用:
1 @Autowired 2 private ShoppingCarService shoppingCarService; 3 4 @Autowired 5 private MemberService memberService; 6 7 @Autowired 8 private MsgSender msgSender;
二、使用@service注解
a)如何定义?
即在具体的实现了方法加入@service注解
b)如何使用?
使用@Autowired 注解注入或构造函数注入
1 @Service 2 public class MemberServiceImpl implements MemberService { 3 @Override 4 public String getUserNameById(String userId) { 5 //TODO 6 return userId+":name"; 7 } 8 }
使用:
1 @Autowired 2 private MemberService memberService;
三、自定义条件bean
所谓自定义条件bean就是在springboot上下文启动的时候可以根据条件的判断初始化满足特定条件的bean,例如: 在项目中我们需要发送消息到QQ或微信,可以在系统启动的时候通过配置文件进行指定,但是我们发送的实现方式是不一样的。这时候可以选择使用条件bean。
条件bean的使用步骤:
1)定义条件判断class
在类启动加载的时候返回true条件的bean会被初始化,在本例中我们先定义两个条件class如下需要继承Condition ,主要判断为配置文件配置的属性msg.sender 为QQ还是为Webchat。
1 public class MsgSenderConditionQQ implements Condition { 2 3 @Override 4 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 5 String msg = context.getEnvironment().getProperty("msg.sender"); 6 return "QQ".equals(msg); 7 } 8 } 9 public class MsgSenderConditionWebchat implements Condition { 10 11 @Override 12 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 13 String msg = context.getEnvironment().getProperty("msg.sender"); 14 return "Webchat".equals(msg); 15 } 16 }
2)bean的初始化
bean的初始化定义到configuration类中,多一个注解@Conditional(MsgSenderConditionQQ.class) 并指定需要进行条件判断的class
1 /** 2 * 条件bean 3 * @return 4 */ 5 @Bean 6 @Conditional(MsgSenderConditionQQ.class) 7 MsgSender initMsgSenderQQ() { 8 System.out.println("QQ msg sender init"); 9 return new MsgSenderQQ(); 10 } 11 12 /** 13 * 条件bean 14 * @return 15 */ 16 @Bean 17 @Conditional(MsgSenderConditionWebchat.class) 18 MsgSender initMsgSenderWebchat() { 19 System.out.println("webchat msg sender init"); 20 return new MsgSenderWebchat(); 21 }
3)配置文件加入判断条
配置判断属性为QQ,即选择加载QQ消息发送bean进行注入。
1 #端口 2 server: 3 port: 8080 4 spring: 5 application: 6 #名称 7 name: start 8 9 #自定义属性 Webchat QQ 10 msg: 11 sender: QQ
4)bean的启动
四、bean的初始化与销毁
bean的初始化与销毁主要有两种方式
方式一:在configuration中使用 @bean 注解方式指定注解属性
1 /** 2 * 显式指定bean的名称,初始化调用方法即销毁调用方法 3 * @return 4 */ 5 @Bean(name = "priceBean",initMethod = "init",destroyMethod = "destroy") 6 PriceService initPriceBean() { 7 return new PriceServiceImpl(); 8 }
在priceServiceImpl实现类中写init方法和destory方法:
public class PriceServiceImpl implements PriceService{ public void init(){ System.out.println("bean init start..."); } @Override public Double getPriceByProductCode(String productCode) { //TODO return new Double(1.2); } public void destroy(){ System.out.println("bean destory..."); } }
方法二:使用方法注解 @PostConstruct @PreDestory
public class ProductServiceImpl implements ProductService { @PostConstruct public void init(){ System.out.println("product bean init"); } @Override public String getProductNameByProductCode(String id) { //TODO return "可乐"; } @PreDestroy public void destroy(){ System.out.println("product bean desory"); } }
五、自带的部分条件bean的使用
@ConditionalOnProperty(name="condition.onPropertyCondition",havingValue="true",matchIfMissing=true)
只有配置文件中(springBoot读取的配置文件)有 condition.onPropertyCondition且该值为 true 时才装配该Bean,如果该配置没有value,使用matchIfMissing=true 也能装配该Bean。
@ConditionalOnBean(name={"onPropertyCondition","dfgdfg"})
指定的Bean中只要有一个Bean存在于Spring IOC container 中则该Bean被装配
1 @ConditionalOnMissingBean(name={"123","dfgdfg"})
指定的Bean中只要有一个Bean不存在于Spring IOC container 中则该Bean被装配
@ConditionalOnClass(name={"com.google.gson.Gson"})
指定的class 必须全在classpath中存在 且逻辑合理
@ConditionalOnMissingClass(value={"com.google.gson.Gson",""})
指定的class 必须都不在classpath 且逻辑合理
参考链接:https://zhuanlan.zhihu.com/p/37967769