编写不易,转载请注明(http://shihlei.iteye.com/blog/2405771)!
一 @Configuration 概述
@Bean: 描述@Bean注解的方法生成的Bean 被Spring容器管理, 其中value属性可以指定Bean在Spring容器中的名字。
@Configuration:描述@Configuration注解的类,Spring容器扫描@Bean注解的方法,将生成的Bean纳入容器管理(可以简化xml配置) 。
存在于:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version${spring.version}</version> </dependency>
二 使用Demo
(一)配置类
package x.demo.spring.context.conf.define; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SimpleConfiguraiton { @Bean public BeanInSimple beanInSimple() { return new BeanInSimple(); } } class BeanInSimple { }
(二)Spring容器引导@Configuration 的几种方法
方法1 :
通过AnnotationConfigApplicationContext 或 web 版 AnnotationConfigWebApplicationContext 引导Bean导入容器
package x.demo.spring.context.conf; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.support.ClassPathXmlApplicationContext; import x.demo.spring.context.conf.define.EnvConfiguration; import x.demo.spring.context.conf.define.ProfileConfiguration; import x.demo.spring.context.conf.define.RealConfiguration; import x.demo.spring.context.conf.define.SimpleConfiguraiton; public class ConfigurationAnnocationDemo { //打印相关信息 private static void show(ApplicationContext context) { String[] beans = {"beanInSimple"}; for (String b : beans) { boolean isContains = context.containsBean(b); System.out.println(b + " is exist : " + isContains); if (isContains) { System.out.println(b + " : " + context.getBean(b)); } } } /** * 通过AnnotationConfigApplicationContext 或 web 版 AnnotationConfigWebApplicationContext 直接注册配置类,驱动Bean导入容器 */ public static void triggerViaAnnotationConfigApplicationContext() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();) { context.register(SimpleConfiguraiton.class); context.refresh(); show(context); } } public static void main(String[] args) { ConfigurationAnnocationDemo.triggerViaAnnotationConfigApplicationContext(); } }
方法2:
通过Spring Xml文件引导Bean导入容器
xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:annotation-config/> <bean class="x.demo.spring.context.conf.define.SimpleConfiguraiton"/> </beans>
程序:
package x.demo.spring.context.conf; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.support.ClassPathXmlApplicationContext; import x.demo.spring.context.conf.define.EnvConfiguration; import x.demo.spring.context.conf.define.ProfileConfiguration; import x.demo.spring.context.conf.define.RealConfiguration; import x.demo.spring.context.conf.define.SimpleConfiguraiton; public class ConfigurationAnnocationDemo { //打印相关信息 private static void show(ApplicationContext context) { String[] beans = {"beanInSimple"}; for (String b : beans) { boolean isContains = context.containsBean(b); System.out.println(b + " is exist : " + isContains); if (isContains) { System.out.println(b + " : " + context.getBean(b)); } } } /** * xml 方式触发@ComponentScan使用 */ public static void triggerViaXml() { try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ("classpath:x.demo.spring.context.conf/spring-conf.xml");) { show(context); } } public static void main(String[] args) { ConfigurationAnnocationDemo.triggerViaXml(); } }
方法3:
通过ComponentScan 引导Bean导入容器:可参考之前的文章《Spring:@ComponentScan 使用》
package x.demo.spring.context.conf; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.support.ClassPathXmlApplicationContext; import x.demo.spring.context.conf.define.EnvConfiguration; import x.demo.spring.context.conf.define.ProfileConfiguration; import x.demo.spring.context.conf.define.RealConfiguration; import x.demo.spring.context.conf.define.SimpleConfiguraiton; @ComponentScan("x.demo.spring.context.conf.define") public class ConfigurationAnnocationDemo { //打印相关信息 private static void show(ApplicationContext context) { String[] beans = {"beanInSimple"}; for (String b : beans) { boolean isContains = context.containsBean(b); System.out.println(b + " is exist : " + isContains); if (isContains) { System.out.println(b + " : " + context.getBean(b)); } } } /** * 通过ComponentScan 引导Bean导入容器 */ public static void triggerViaComponentScan() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();) { context.register(ConfigurationAnnocationDemo.class); context.refresh(); show(context); } } public static void main(String[] args) { ConfigurationAnnocationDemo.triggerViaComponentScan(); } }
(二)结果
beanInSimple is exist : true beanInSimple : x.demo.spring.context.conf.define.BeanInSimple@4c15e7fd
三 读取配置初始化@Configuration中的Bean
可以通过 @PropertySource() 或 @Value 加载配置文件中的数据,初始化Bean
配置文件:classpath:x.demo.spring.context.conf/env.properties
x.demo.spring.context.conf.define.env=dev
程序:
package x.demo.spring.context.conf.define; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration //导入属性文件 @PropertySource("classpath:x.demo.spring.context.conf/env.properties") public class EnvConfiguration { //获取整个配置文件值 @Resource Environment env; //获取属性文件中指定key的信息 @Value("${x.demo.spring.context.conf.define.env}") String envValue; @Bean public BeanInEnv beanInEnv() { System.out.println("env reads : " + env.getProperty("x.demo.spring.context.conf.define.env")); System.out.println("env @Value : " + envValue); return new BeanInEnv(envValue); } } class BeanInEnv { public BeanInEnv(String env) { } }
四 组合其他@Configutration定义
@Configuration 可以组合其他的注解,来生成合并的配置
(1)使用@Import:
导入其他@Configuration注解的类 或 有@Bean注解方法的类。多用于@Configuration 类导入依赖。
(2)使用@ImportResource:
从Xml中读取Bean定义,组合Bean 配置。
(3)使用静态内部类:
Demo:
BaseConfiguration:
package x.demo.spring.context.conf.define; import org.springframework.context.annotation.Bean; public class BaseConfiguration { @Bean public BeanInBase beanInBase() { return new BeanInBase(); } } class BeanInBase { }
Xml bean定义:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="x.demo.spring.context.conf.define.BeanInRealXmlDependency"/> </beans>
RealConfiguration:
package x.demo.spring.context.conf.define; import javax.annotation.Resource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportResource; @Configuration //导入其他的配置 @Import(BaseConfiguration.class) //从Xml文件导入Bean定义 @ImportResource("classpath:x.demo.spring.context.conf/spring-xml-dependency.xml") public class RealConfiguration { @Resource BeanInRealXmlDependency beanInRealXmlDependency; @Resource BeanInRealNestedDependency beanInRealNestedDependency; @Bean public BeanInReal beanInReal() { return new BeanInReal(beanInRealXmlDependency, beanInRealNestedDependency); } //静态内部类方式导入定义 @Configuration static class NestedConfiguration { @Bean public BeanInRealNestedDependency beanInRealNestedDependency() { return new BeanInRealNestedDependency(); } } } class BeanInReal { public BeanInReal(BeanInRealXmlDependency beanInRealXmlDependency, BeanInRealNestedDependency beanInRealNestedDependency) { System.out.println("beanInRealXmlDependency : " + beanInRealXmlDependency); System.out.println("beanInRealNestedDependency : " + beanInRealNestedDependency); } } class BeanInRealNestedDependency { } class BeanInRealXmlDependency { }
五 根据条件生成Bean导入Spring容器
(1)根据@Profile:
在某个Profile激活的时候使用某个配置:
package x.demo.spring.context.conf.define; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration public class ProfileConfiguration { @Bean() @Profile("dev") public BeanInProfile beanInRealOnDev() { return new BeanDev(); } @Bean() @Profile("online") public BeanInProfile beanInRealOnOnline() { return new BeanOnline(); } } class BeanInProfile { } class BeanDev extends BeanInProfile { } class BeanOnline extends BeanInProfile { }
注:测试是要添加虚拟机参数指定激活那个profile
(2)根据@Conditional
@Conditional 可以指定条件,根据条件确定是否生成Bean
这里简单实现了根据数据库是否有驱动,实例化某个Bean
package x.demo.spring.context.conf.define; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Map; import java.util.Objects; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.type.AnnotatedTypeMetadata; @Configuration public class ConditionalConfiguration { @Bean @ConditionalOnDBDriver(driver = "com.mysql.jdbc.Driver") public BeanDB beanMySql() { return new BeanMySql(); } @Bean @ConditionalOnDBDriver(driver = "oracle.jdbc.driver.OracleDriver") public BeanDB beanOracle() { return new BeanOracle(); } } class BeanDB { } class BeanMySql extends BeanDB { } class BeanOracle extends BeanDB { } @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnDBDriverCondition.class) @interface ConditionalOnDBDriver { /** * 驱动名称 * * @return 驱动名称 */ String driver(); } /** * 加载条件 */ class OnDBDriverCondition implements Condition { /** * 匹配条件:某个类在class path下某个指定名字的类是否存在, * <p> * 注:其他需求可以配合maven <optional>true</optional>,使用 * * @param context 条件上线文,包括beanFactory , env,classloader 等 * @param metadata 元数据,提供被注解的类,方法信息 * @return true 注册到容器,false 不注册到容器 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { try { Map<String, Object> attributes = metadata.getAnnotationAttributes("x.demo.spring.context.conf.define.ConditionalOnDBDriver"); if (Objects.isNull(attributes)) { return false; } String driver = String.valueOf(attributes.get("driver")); System.out.println("[debug] driver : " + driver); Class.forName(driver); return true; } catch (ClassNotFoundException e) { return false; } } }
注:如果要 向容器注入BeanMySql需要添加MySql依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> <optional>true</optional> </dependency>
六 完成测试程序
结构:
代码:
package x.demo.spring.context.conf; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.support.ClassPathXmlApplicationContext; import x.demo.spring.context.conf.define.EnvConfiguration; import x.demo.spring.context.conf.define.ProfileConfiguration; import x.demo.spring.context.conf.define.RealConfiguration; import x.demo.spring.context.conf.define.SimpleConfiguraiton; @ComponentScan("x.demo.spring.context.conf.define") public class ConfigurationAnnocationDemo { //打印相关信息 private static void show(ApplicationContext context) { String[] beans = {"beanInSimple", "beanInBase", "beanInEnv", "beanInReal", "beanInProfile","beanInRealOnDev", "beanInRealOnOnline","beanMySql","beanOracle"}; for (String b : beans) { boolean isContains = context.containsBean(b); System.out.println(b + " is exist : " + isContains); if (isContains) { System.out.println(b + " : " + context.getBean(b)); } } } /** * 通过AnnotationConfigApplicationContext 或 web 版 AnnotationConfigWebApplicationContext 直接注册配置类,驱动Bean导入容器 */ public static void triggerViaAnnotationConfigApplicationContext() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();) { context.register(SimpleConfiguraiton.class, EnvConfiguration.class, RealConfiguration.class, ProfileConfiguration.class); context.refresh(); show(context); } } /** * xml 方式触发@ComponentScan使用 */ public static void triggerViaXml() { try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ("classpath:x.demo.spring.context.conf/spring-conf.xml");) { show(context); } } /** * 通过ComponentScan 引导Bean导入容器 */ public static void triggerViaComponentScan() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();) { context.register(ConfigurationAnnocationDemo.class); context.refresh(); show(context); } } public static void main(String[] args) { ConfigurationAnnocationDemo.triggerViaComponentScan(); } }
结果:
[debug] driver : com.mysql.jdbc.Driver [debug] driver : oracle.jdbc.driver.OracleDriver env reads : dev env @Value : dev beanInRealXmlDependency : x.demo.spring.context.conf.define.BeanInRealXmlDependency@7a52f2a2 beanInRealNestedDependency : x.demo.spring.context.conf.define.BeanInRealNestedDependency@78047b92 beanInSimple is exist : true beanInSimple : x.demo.spring.context.conf.define.BeanInSimple@60dcc9fe beanInBase is exist : true beanInBase : x.demo.spring.context.conf.define.BeanInBase@222114ba beanInEnv is exist : true beanInEnv : x.demo.spring.context.conf.define.BeanInEnv@16e7dcfd beanInReal is exist : true beanInReal : x.demo.spring.context.conf.define.BeanInReal@3d121db3 beanInProfile is exist : false beanInRealOnDev is exist : true beanInRealOnDev : x.demo.spring.context.conf.define.BeanDev@3b07a0d6 beanInRealOnOnline is exist : false beanMySql is exist : true beanMySql : x.demo.spring.context.conf.define.BeanMySql@11a9e7c8 beanOracle is exist : false
相关推荐
* @Qualifier:@Autowired注解配合使用,会将默认的按Bean类型装配修改为按照Bean实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。 五、基于JavaConfig的配置形式 在实际开发中,Spring Boot社区推荐...
Spring Framework 中@Configuration 注解的重要性 @Configuration 注解是 Spring Framework 中的一个重要组件,它用于标注配置类,告诉 Spring Framework 如何处理 Bean 的创建和管理。在本文中,我们将深入探讨为...
} }配置类:@Configuration public class MyConfig { @Bean public UserBean createUserBean() { return new UserBean("test", "123456"); } }测试类:public class TestConfig { public static void main(String[]...
### Spring 4.0 中 @Configuration 的使用详解 #### 一、@Configuration 基础概念及使用场景 - **@Configuration** 注解自 Spring 3.0 引入,旨在提供一种基于 Java 的配置方式来替代传统的 XML 配置文件。通过...
赠送jar包:spring-boot-configuration-processor-2.3.12.RELEASE.jar; 赠送原API文档:spring-boot-configuration-processor-2.3.12.RELEASE-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-...
该项目提供了,如果在Spring 类中遇到以下情况之一,该将发出编译器警告和错误: @Configuration类不能是最终的。 @Configuration类必须具有可见的无参数构造函数。 @Configuration类的构造函数不得为@Autowired...
在Spring框架中,`@Configuration`和`@Bean`是非常重要的两个注解,它们被广泛应用于定义Spring容器中的Bean以及Bean的配置方式。传统的Spring配置是通过XML文件来完成的,而在现代的Java开发中,更倾向于采用基于...
赠送jar包:spring-boot-configuration-processor-2.5.6.jar; 赠送原API文档:spring-boot-configuration-processor-2.5.6-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-2.5.6-sources.jar; ...
赠送jar包:spring-boot-configuration-processor-2.6.3.jar; 赠送原API文档:spring-boot-configuration-processor-2.6.3-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-2.6.3-sources.jar; ...
赠送jar包:spring-boot-configuration-processor-2.0.4.RELEASE.jar; 赠送原API文档:spring-boot-configuration-processor-2.0.4.RELEASE-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-2.0.4....
赠送jar包:spring-boot-configuration-processor-2.6.3.jar; 赠送原API文档:spring-boot-configuration-processor-2.6.3-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-2.6.3-sources.jar; ...
- 如果一个类没有特定的业务角色,只是作为通用工具类,那么可能不需要`@Component`,而是使用`@Configuration`类或XML配置来创建Bean。 3. **派生注解** - `@Service`:通常用于业务逻辑层(Service Layer),它...
在Spring Boot框架中,`@Configuration`注解是核心组件之一,它用于标记一个类作为配置类,使得我们可以使用Java配置来替代XML配置。在这个"自定义@Configuration配置类启用开关.zip"项目中,我们很显然会看到如何...
Spring 中 @Async 注解的使用 @Async 注解是 Spring 框架提供的一种异步执行方法的实现方式,从 Spring 3.0 版本开始提供。使用 @Async 注解可以将方法标识为异步方法,通过 SimpleAsyncTaskExecutor 执行,但不...
赠送jar包:spring-boot-configuration-processor-2.0.4.RELEASE.jar; 赠送原API文档:spring-boot-configuration-processor-2.0.4.RELEASE-javadoc.jar; 赠送源代码:spring-boot-configuration-processor-2.0.4....
拦截器 , 过滤器 , 序列化 , @After , @AfterReturning , @AfterThrowing , @annotation , @Around , @Aspect , @Autowired , @Bean , @Before , @Component , @ComponentScan , @ComponentScans , @Configuration ...
@SpringBootApplication 注解是 Spring Boot 的核心注解,它是一个组合注解,实际上是三个 Annotation 的组合:@Configuration、@EnableAutoConfiguration 和 @ComponentScan。这些注解的结合使用,使得 Spring Boot ...
Spring 中 @Import 注解的作用和使用 @Import 注解是 Spring 框架中的一种重要注解,主要用于导入@Configuration 注解的配置类、声明@Bean 注解的 bean 方法、导入 ImportSelector 的实现类或导入 ...
`@Conditional`注解通常与`@Configuration`或`@Bean`注解一起使用。它的主要作用是基于某些条件来判断bean是否应该生效。这些条件可以通过自定义的条件类(实现`Condition`接口)来定义。条件类通常会检查系统属性、...