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

posted @ 2020-10-18 15:41  John_yan15  阅读(4033)  评论(1编辑  收藏  举报