目录:
- bean的加载方式(—)
- bean的加载方式(二)
- bean的加载方式(三)
- FactoryBean
- proxyBeanMethod属性
- bean的加载方式(四)
- bean的加载方式(五)
- bean的加载方式(六)
- bean的加载方式(七)
- bean的加载方式(八)
- bean加载控制(编程式)
- bean加载控制(注解式)
- bean依赖属性配置
1.bean的加载方式(—)
XML方式声明bean
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>springboot_27_bean_init</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency></dependencies>
</project>
App1.class
package cn.hdc.app;import cn.hdc.bean.Dog;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App1 {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml");
// Object cat = ctx.getBean("cat");
// System.out.println(cat);
//
// Dog dog = ctx.getBean(Dog.class);
// System.out.println(dog);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
Cat.class
package cn.hdc.bean;public class Cat {
}
Dog.class
package cn.hdc.bean;public class Dog {
}
Mouse.class
package cn.hdc.bean;public class Mouse {
}
BookServiceImpl1.class
package cn.hdc.service.impl;import cn.hdc.service.BookService;public class BookServiceImpl1 implements BookService {@Overridepublic void check() {System.out.println("book service 1...");}
}
BookServiceImpl2.class
package cn.hdc.service.impl;import cn.hdc.service.BookService;public class BookServiceImpl2 implements BookService {@Overridepublic void check() {System.out.println("book service 2...");}
}
BookServiceImpl3.class
package cn.hdc.service.impl;import cn.hdc.service.BookService;public class BookServiceImpl3 implements BookService {@Overridepublic void check() {System.out.println("book service 3...");}
}
BookServiceImpl4.class
package cn.hdc.service.impl;import cn.hdc.service.BookService;public class BookServiceImpl3 implements BookService {@Overridepublic void check() {System.out.println("book service 3...");}
}
BookService.interface
package cn.hdc.service;public interface BookService {void check();
}
applicationContext1.xml
<?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 id="cat" class="cn.hdc.bean.Cat"></bean><bean class="cn.hdc.bean.Dog"></bean><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean>
</beans>
applicationContext2.xml
<?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">
</beans>
2.bean的加载方式(二)
XML+注解方式声明bean
使用@Component及其衍生注解@Controller . @Service、@Repository定义bean
使用@Bean定义第三方bean,并将所在类定义为配置类或Bean
applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="cn.hdc.bean,cn.hdc.config"/>
</beans>
App2.class
package cn.hdc.app;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App2 {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext2.xml");String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
Dbconfig.class
package cn.hdc.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class DbConfig {@Beanpublic DruidDataSource dataSource() {DruidDataSource ds = new DruidDataSource();return ds;}
}
3.bean的加载方式(三)
注解方式声明配置类
App3.class
package cn.hdc.app;import cn.hdc.config.SpringConfig3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App3 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig3.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
SpringConfig3.class
package cn.hdc.config;import org.springframework.context.annotation.ComponentScan;@ComponentScan({"cn.hdc.bean","cn,hdc.config"})
public class SpringConfig3 {
}
4.FactoryBean
注解方式声明配置类
@Configuration配置项如果不用于被扫描可以省略
初始化实现FactoryBean接口的类,实现对bean加载到容器之前的批处理操作
App4.class
package cn.hdc.app;import cn.hdc.config.SpringConfig4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App4 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig4.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}System.out.println(ctx.getBean("dog"));System.out.println(ctx.getBean("dog"));System.out.println(ctx.getBean("dog"));}
}
DogFactoryBean.class
package cn.hdc.bean;import org.springframework.beans.factory.FactoryBean;public class DogFactoryBean implements FactoryBean<Dog> {@Overridepublic Dog getObject() throws Exception {return new Dog();}@Overridepublic Class<?> getObjectType() {return Dog.class;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}
SpringConfig4.class
package cn.hdc.config;import cn.hdc.bean.Dog;
import cn.hdc.bean.DogFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;@ComponentScan({"cn.hdc.bean", "cn,hdc.config"})
public class SpringConfig4 {
// @Bean
// public Dog dog() {
// return new Dog();
// }@Beanpublic DogFactoryBean dog() {return new DogFactoryBean();}
}
5.proxyBeanMethod属性
加载配置类并加载配置文件(系统迁移)
App32.class
package cn.hdc.app;import cn.hdc.config.SpringConfig32;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App32 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig32.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
SpringConfig32.class
package cn.hdc.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;@ComponentScan({"cn.hdc.bean", "cn,hdc.config"})
@ImportResource("applicationContext1.xml")
@Component
public class SpringConfig32 {
}
applicationContext1.xml
<?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 id="cat" class="cn.hdc.bean.Cat"></bean><bean class="cn.hdc.bean.Dog"></bean><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean><bean class="com.alibaba.druid.pool.DruidDataSource"></bean><bean class="com.alibaba.druid.pool.DruidDataSource"></bean>
</beans>
使用proxyBeanMethods=true可以保障调用此方法得到的对象是从容器中获取的而不是重新创建的
App33.class
package cn.hdc.app;import cn.hdc.config.SpringConfig33;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App33 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig33.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}System.out.println("----------------------------");SpringConfig33 springConfig33 = ctx.getBean("springConfig33", SpringConfig33.class);System.out.println(springConfig33.cat());System.out.println(springConfig33.cat());System.out.println(springConfig33.cat());}
}
SpringConfig33.class
package cn.hdc.config;import cn.hdc.bean.Cat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration(proxyBeanMethods = false)
public class SpringConfig33 {@Beanpublic Cat cat() {return new Cat();}
}
6.bean的加载方式(四)
使用@Import注解导入要注入的bean对应的字节码
被导入的bean无需使用注解声明为bean
此形式可以有效的降低源代码与Spring技术的耦合度,在spring技术底层及诸多框架的整合中大量使用
使用@lmport注解导入配置类
App4.class
package cn.hdc.app;import cn.hdc.bean.Dog;
import cn.hdc.config.SpringConfig4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App4 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig4.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}System.out.println("-----------------");System.out.println(ctx.getBean(Dog.class));}
}
SpringConfig4.class
package cn.hdc.config;import cn.hdc.bean.Dog;
import org.springframework.context.annotation.Import;@Import({Dog.class, DbConfig.class})
public class SpringConfig4 {}
7.bean的加载方式(五)
使用上下文对象在容器初始化完毕后注入bean
App5.class
package cn.hdc.app;import cn.hdc.bean.Cat;
import cn.hdc.bean.Mouse;
import cn.hdc.config.SpringConfig5;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App5 {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig5.class);ctx.registerBean("tom", Cat.class, 0);ctx.registerBean("tom", Cat.class, 1);ctx.registerBean("tom", Cat.class, 2);ctx.register(Mouse.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}System.out.println(ctx.getBean(Cat.class));}
}
SpringConfig5.class
package cn.hdc.config;public class SpringConfig5 {}
Cat.class
package cn.hdc.bean;import org.springframework.stereotype.Component;@Component("tom")
public class Cat {int age;public Cat() {}public Cat(int age) {this.age = age;}@Overridepublic String toString() {return "Cat{" +"age=" + age +'}';}
}
Dog.class
package cn.hdc.bean;import org.springframework.stereotype.Service;//@Service("jerry")
public class Mouse {
}
8.bean的加载方式(六)
导入实现了ImportSelector接口的类,实现对导入源的编程式处理
App6.class
package cn.hdc.app;import cn.hdc.config.SpringConfig6;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App6 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig6.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
SpringConfig.class
package cn.hdc.config;import cn.hdc.bean.MyImportSelector;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Import(MyImportSelector.class)
@Configuration
//@ComponentScan(basePackages = "cn.hdc")
public class SpringConfig6 {}
MyImportSelector.class
package cn.hdc.bean;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;import java.util.Map;public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata metadata) {
// System.out.println("=======================");
// System.out.println("提示:" + metadata.getClassName());
// System.out.println(metadata.hasAnnotation("org.springframework.context.annotation.Configuration"));
// Map<String, Object> attributes = metadata.getAnnotationAttributes("org.springframework.context.annotation.ComponentScan");
// System.out.println(attributes);
// System.out.println("=======================");boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");if (flag) {return new String[]{"cn.hdc.bean.Dog"};}return new String[]{"cn.hdc.bean.Cat"};}
}
9.bean的加载方式(七)
导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果
App7.class
package cn.hdc.app;import cn.hdc.config.SpringConfig7;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App7 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig7.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}
SpringConfig7.class
package cn.hdc.config;import cn.hdc.bean.MyRegistar;
import org.springframework.context.annotation.Import;@Import(MyRegistar.class)
public class SpringConfig7 {}
MyRegistar.class
package cn.hdc.bean;import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class MyRegistar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();registry.registerBeanDefinition("red", beanDefinition);}
}
10.bean的加载方式(八)
导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的最终裁定
App8.class
package cn.hdc.app;import cn.hdc.bean.service.BookService;
import cn.hdc.config.SpringConfig8;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App8 {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig8.class);BookService bookService = ctx.getBean("bookService", BookService.class);bookService.check();}
}
SpringConfig8.class
package cn.hdc.config;import cn.hdc.bean.MyPostProcessor;
import cn.hdc.bean.MyRegistar;
import cn.hdc.bean.MyRegistar2;
import cn.hdc.bean.service.impl.BookServiceImpl1;
import org.springframework.context.annotation.Import;@Import({BookServiceImpl1.class, MyRegistar.class, MyRegistar2.class, MyPostProcessor.class})
public class SpringConfig8 {}
MyRegistar.class
package cn.hdc.bean;import cn.hdc.bean.service.BookService;
import cn.hdc.bean.service.impl.BookServiceImpl2;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class MyRegistar implements ImportBeanDefinitionRegistrar {// @Override
// public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
// BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
//
// registry.registerBeanDefinition("red", beanDefinition);
// }@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}
}
MyRegistar2.class
package cn.hdc.bean;import cn.hdc.bean.service.impl.BookServiceImpl2;
import cn.hdc.bean.service.impl.BookServiceImpl3;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class MyRegistar2 implements ImportBeanDefinitionRegistrar {// @Override
// public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
// BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
//
// registry.registerBeanDefinition("red", beanDefinition);
// }@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl3.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}
}
MyPostProcessor.class
package cn.hdc.bean;import cn.hdc.bean.service.impl.BookServiceImpl4;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}
BookServiceImpl1.class
package cn.hdc.bean.service.impl;import cn.hdc.bean.service.BookService;
import org.springframework.stereotype.Service;@Service("bookService")
public class BookServiceImpl1 implements BookService {@Overridepublic void check() {System.out.println("book service 1...");}
}
BookServiceImpl2.class
package cn.hdc.bean.service.impl;import cn.hdc.bean.service.BookService;public class BookServiceImpl2 implements BookService {@Overridepublic void check() {System.out.println("book service 2...");}
}
BookServiceImpl3.class
package cn.hdc.bean.service.impl;import cn.hdc.bean.service.BookService;public class BookServiceImpl3 implements BookService {@Overridepublic void check() {System.out.println("book service 3...");}
}
BookServiceImpl4.class
package cn.hdc.bean.service.impl;import cn.hdc.bean.service.BookService;public class BookServiceImpl4 implements BookService {@Overridepublic void check() {System.out.println("book service 4...");}
}
11.bean加载控制(编程式)
根据任意条件确认是否加载bean
Cat.class
package cn.hdc.bean;import org.springframework.stereotype.Component;@Component("tom")
public class Cat {
}
Dog.class
package cn.hdc.bean;public class Dog {
}
Mouse.class
package cn.hdc.bean;public class Mouse {
}
MyImportSelector.class
package cn.hdc.bean;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {try {Class<?> clazz = Class.forName("cn.hdc.bean.Mouse");if (clazz != null) {return new String[]{"cn.hdc.bean.Cat"};}} catch (ClassNotFoundException e) {return new String[0];}return null;}
}
SpringConfig.class
package cn.hdc.config;import cn.hdc.bean.MyImportSelector;
import org.springframework.context.annotation.Import;@Import(MyImportSelector.class)
public class SpringConfig {
}
App.class
package cn.hdc;import cn.hdc.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);String[] beans = context.getBeanDefinitionNames();for (String bean : beans) {System.out.println(bean);}}
}
12.bean加载控制(注解式)
根据任意条件确认是否加载bean
使用@Conditional注解的派生注解设置各种组合条件控制bean的加载
匹配指定类
未匹配指定类
匹配指定类型的bean
匹配指定名称的bean
匹配指定环境
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>springboot_28_bean_load</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.5.4</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency></dependencies></project>
Cat.class
package cn.hdc.bean;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.stereotype.Component;@Component("tom")
@ConditionalOnBean(name = "jerry")
//@ConditionalOnWebApplication
@ConditionalOnNotWebApplication
public class Cat {
}
Dog.class
package cn.hdc.bean;public class Dog {
}
Mouse.class
package cn.hdc.bean;import org.springframework.stereotype.Component;@Component("jerry")
public class Mouse {
}
MyImportSelector.class
package cn.hdc.bean;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {try {Class<?> clazz = Class.forName("cn.hdc.bean.Mouse");if (clazz != null) {return new String[]{"cn.hdc.bean.Cat"};}} catch (ClassNotFoundException e) {return new String[0];}return null;}
}
SpringConfig.class
package cn.hdc.config;import cn.hdc.bean.Cat;
import cn.hdc.bean.Dog;
import cn.hdc.bean.Mouse;
import cn.hdc.bean.MyImportSelector;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;//@Import(MyImportSelector.class)
//@Import(Mouse.class)
@ComponentScan("cn.hdc.bean")
public class SpringConfig {
// @Bean@ConditionalOnClass(name = "cn.hdc.bean.Mouse")@ConditionalOnMissingClass("cn.hdc.bean.Wolf")
// @ConditionalOnBean(name = "jerry")@ConditionalOnMissingClass("cn.hdc.bean.Dog")
// @ConditionalOnNotWebApplication@ConditionalOnWebApplication
// public Cat tom() {
// return new Cat();
// }@Bean@ConditionalOnClass(name = "com.mysql.jdbc.Driver")public DruidDataSource dataSource() {return new DruidDataSource();}
}
13.bean依赖属性配置
将业务功能bean运行需要的资源抽取成独立的属性类(******Properties),设置读取配置文件信息
配置文件中使用固定格式为属性类注入数据
定义业务功能bean,通常使用@Import导入,解耦强制加载bean
使用@EnableConfigurationProperties注解设定使用属性类时加载bean
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>springboot_29_bean_properties</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot_29_bean_properties</name><description>springboot_29_bean_properties</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image></configuration></plugin></plugins></build></project>
CartoonCatAndMouse.class
package com.example.springboot_29_bean_properties.bean;import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;@Data
@EnableConfigurationProperties(CartoonProperties.class)
public class CartoonCatAndMouse {private Cat cat;private Mouse mouse;private CartoonProperties cartoonProperties;public CartoonCatAndMouse(CartoonProperties cartoonProperties) {this.cartoonProperties = cartoonProperties;cat = new Cat();cat.setName(cartoonProperties.getCat() != null && StringUtils.hasText(cartoonProperties.getCat().getName()) ? cartoonProperties.getCat().getName() : "tom");cat.setAge(cartoonProperties.getCat() != null && cartoonProperties.getCat().getAge() != null ? cartoonProperties.getCat().getAge() : 3);mouse = new Mouse();mouse.setName(cartoonProperties.getMouse() != null && StringUtils.hasText(cartoonProperties.getCat().getName()) ? cartoonProperties.getMouse().getName() : "jerry");mouse.setAge(cartoonProperties.getMouse() != null && cartoonProperties.getMouse().getAge() != null ? cartoonProperties.getMouse().getAge() : 4);}public void play() {System.out.println(cat.getAge() + "岁的" + cat.getName() + "和" + mouse.getAge() + "岁的" + mouse.getName() + "打起来了");}
}
CartoonProperties.class
package com.example.springboot_29_bean_properties.bean;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "cartoon")
@Data
public class CartoonProperties {private Cat cat;private Mouse mouse;
}
Cat.class
package com.example.springboot_29_bean_properties.bean;import lombok.Data;@Data
public class Cat {private String name;private Integer age;
}
Mouse.class
package com.example.springboot_29_bean_properties.bean;import lombok.Data;@Data
public class Mouse {private String name;private Integer age;
}
Springboot29BeanPropertiesApplicaiton.class
package com.example.springboot_29_bean_properties;import com.example.springboot_29_bean_properties.bean.CartoonCatAndMouse;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;@SpringBootApplication
@Import(CartoonCatAndMouse.class)
public class Springboot29BeanPropertiesApplication {public static void main(String[] args) {ConfigurableApplicationContext ctx = SpringApplication.run(Springboot29BeanPropertiesApplication.class, args);CartoonCatAndMouse bean = ctx.getBean(CartoonCatAndMouse.class);bean.play();}
}
小结:
- 业务bean的属性可以为其设定默认值
- 当需要设置时通过配置文件传递属性
- 业务bean应尽量避免设置强制加载,而是根据需要导入后加载,降低spring容器管理bean的强度