一、@Conditional
@Conditional是Spring4新提供的註解,它的作用是按照一定的條件進行判斷,滿足條件的纔給容器註冊Bean。
代碼例子:
package com.cy.conditional; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:20 */ public interface ListService { public String showListCmd(); }
package com.cy.conditional; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:21 */ public class LinuxListService implements ListService{ @Override public String showListCmd() { return "ls"; } }
package com.cy.conditional; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:21 */ public class WindowsListService implements ListService{ @Override public String showListCmd() { return "dir"; } }
WindowsCondition:
package com.cy.conditional; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:20 */ public class WindowsCondition implements Condition { @Override public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) { return arg0.getEnvironment().getProperty("os.name").contains("Windows"); } }
LinuxCondition:
package com.cy.conditional; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:19 */ public class LinuxCondition implements Condition { @Override public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) { return arg0.getEnvironment().getProperty("os.name").contains("Linux"); } }
配置類Config:
package com.cy.conditional; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:21 */ @Configuration public class ConditionConfig { @Bean @Conditional(WindowsCondition.class) public ListService windowsListService() { return new WindowsListService(); } @Bean @Conditional(LinuxCondition.class) public ListService linuxListService() { return new LinuxListService(); } }
測試類:
package com.cy.conditional; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:22 */ public class App { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext( ConditionConfig.class); ListService ls = context.getBean(ListService.class); System.out.println(context.getEnvironment().getProperty("os.name") + "系統下的列表命令爲:" + ls.showListCmd()); } }
console:
Windows 10系統下的列表命令爲:dir
二、@ConditionalOnClass
例如:@ConditionalOnClass(KafkaTemplate.class)
表示:Spring工程中引用了Kafka的包 纔會構建這個bean。就是說只有在classpath下能找到kafkaTemplate類纔會構建這個bean。
三、@ConditionalOnBean
@ConditionalOnBean(僅僅在當前上下文中存在某個對象時,纔會實例化一個Bean)
參考博客:https://www.cnblogs.com/qdhxhz/p/11027546.html
代碼例子:
1.實體類:
package com.cy.model; import lombok.Getter; import lombok.Setter; import lombok.ToString; /** * @description com.cy.model * @author: chengyu * @date: 2022-04-22 11:40 */ @Setter @Getter @ToString public class Mother { String name; int age; Son son; }
package com.cy.model; import lombok.Getter; import lombok.Setter; import lombok.ToString; /** * @description com.cy.model * @author: chengyu * @date: 2022-04-22 11:40 */ @Setter @Getter @ToString public class Son { String name; int age; }
2.配置類:
package com.cy.conditional; import com.cy.model.Mother; import com.cy.model.Son; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ConditionConfig { /*@Bean public Son son(){ Son s = new Son(); s.setAge(10); s.setName("小明"); return s; }*/ @Bean @ConditionalOnBean(Son.class) public Mother mother(Son son){ Mother m = new Mother(); m.setAge(40); m.setName("小慧媽媽"); m.setSon(son); return m; } }
3.測試類:
package com.cy.conditional; import com.cy.model.Mother; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @description com.cy.conditional * @author: chengyu * @date: 2022-04-22 11:37 */ @Controller @Slf4j public class ConditionController { @Autowired(required = false) private Mother mother; @ResponseBody @RequestMapping("/testConditionOnBean") public void conditionOnBean() { System.out.println(mother); } }
4.測試結果:
a.當不存在Son實體類被注入時,如果private Mother mother上面直接是@Autowired時,啓動就會報錯:
Field mother in com.cy.conditional.ConditionController required a bean of type 'com.cy.model.Mother' that could not be found.
因此需要在@Autowired後面寫上(required=false),required=false 的意思就是允許當前的Bean對象爲null。正常啓動後打印:null
b.當打開Son @Bean的註釋後,重新啓動,控制檯打印:
Mother(name=小慧媽媽, age=40, son=Son(name=小明, age=10))
四、其他的
@ConditionalOnClass(某個class位於類路徑上,纔會實例化一個Bean)
@ConditionalOnExpression(當表達式爲true的時候,纔會實例化一個Bean)
@ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean)
@ConditionalOnMissingClass(某個class類路徑上不存在的時候,纔會實例化一個Bean)
@ConditionalOnNotWebApplication(不是web應用)