资料来源:https://www.bilibili.com/video/BV1gW411W7wy/?spm_id_from=333.788.recommend_more_video.10
一、组件注册
1、@Configuration
通过注解注入JavaBean
// 这个配置类也是一个组件@Configuration // 告诉Spring这是一个配置类public class MainConfig {// @Bean注解是给IOC容器中注册一个bean,类型自然就是返回值的类型,id默认是用方法名作为id@Bean(name = "person01") // 指定名称,不然就默认为方法名personpublic Person person() {return new Person("liayun", 20);}}
通过在MainConfig类上加上@Configuration注解,并在方法上加上@Bean注解,就能够将方法中创建的JavaBean注入到Spring的IOC容器中。
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");// Person bean = (Person) applicationContext.getBean("person");// System.out.println(bean);ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);Person bean = applicationContext.getBean(Person.class);System.out.println(bean); // Person [name=lisi, age=20, nickName=null]// 获取Person这个类型的组件在IOC容器中的名字String[] namesForType = applicationContext.getBeanNamesForType(Person.class);for (String name : namesForType) {System.out.println(name); // person01,若没有指定名称,就默认为方法名person}
2、@ComponentScan
// 配置类==配置文件@Configuration // 告诉Spring这是一个配置类@ComponentScans(value = {@ComponentScan(value="com.atguigu",includeFilters = {/* @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})}, useDefaultFilters = false)})//@ComponentScan value:指定要扫描的包//@ComponentScans 指定多个扫描规则//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件//FilterType.ANNOTATION:按照注解。如Controller.class表示只扫描@Controller注解//FilterType.ASSIGNABLE_TYPE:按照给定的类型;//FilterType.ASPECTJ:使用ASPECTJ表达式//FilterType.REGEX:使用正则指定//FilterType.CUSTOM:使用自定义规则public class MainConfig {// 给容器中注册一个Bean; 类型为返回值的类型,id默认是用方法名作为id@Bean(name = "person01") // 指定名称,不然就默认为方法名personpublic Person person(){return new Person("lisi", 20);}}
// 自定义规则public class MyTypeFilter implements TypeFilter {/*** metadataReader:读取到的当前正在扫描的类的信息* metadataReaderFactory: 可以获取到其他任何类信息的*/@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {// TODO Auto-generated method stub//获取当前类注解的信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//获取当前正在扫描的类的类信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//获取当前类资源(类的路径)Resource resource = metadataReader.getResource();String className = classMetadata.getClassName();System.out.println("--->" +className);if(className.contains("er")){return true; // 匹配成功,给容器中注册bean}return false; // 匹配失败}}
3、@Scope
//默认是单实例的/*** ConfigurableBeanFactory#SCOPE_PROTOTYPE* @see ConfigurableBeanFactory#SCOPE_SINGLETON* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion* @return\* @Scope:调整作用域* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。* 每次获取的时候才会调用方法创建对象;* singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。* 以后每次获取就是直接从容器(map.get())中拿,* request:同一次请求创建一个实例* session:同一个session创建一个实例*/@Scope("prototype")@Bean(name = "person")public Person person(){System.out.println("给容器中添加Person....");return new Person("张三", 25);}
4、@Lazy
/*** 懒加载:* 单实例bean:默认在容器启动的时候创建对象;* 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;*/@Lazy@Bean(name = "person")public Person person(){System.out.println("给容器中添加Person....");return new Person("张三", 25);}
5、@Conditional
// 类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;此时方法上的@Conditional注解会失效@Conditional({WindowsCondition.class})@Configurationpublic class MainConfig2 {/*** @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean** 如果系统是windows,给容器中注册("bill")* 如果是linux系统,给容器中注册("linus")*/// @Conditional({WindowsCondition.class})@Bean(name = "bill")public Person person01(){return new Person("Bill Gates",62);}@Conditional(LinuxCondition.class)@Bean(name = "linus")public Person person02(){return new Person("linus", 48);}}
// 判断是否linux系统public class LinuxCondition implements Condition {/*** ConditionContext:判断条件能使用的上下文(环境)* AnnotatedTypeMetadata:注释信息*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//1、能获取到ioc使用的beanfactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//2、获取类加载器ClassLoader classLoader = context.getClassLoader();//3、获取当前环境信息Environment environment = context.getEnvironment();//4、获取到bean定义的注册类BeanDefinitionRegistry registry = context.getRegistry();String property = environment.getProperty("os.name");//可以判断容器中的bean注册情况,也可以给容器中注册beanboolean definition = registry.containsBeanDefinition("person");if(property.contains("linux")){return true;}return false;}}
// 判断是否windows系统public class WindowsCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 获取IOC容器环境Environment environment = context.getEnvironment();// 动态获取环境变量的值;Windows 10String property = environment.getProperty("os.name");if(property.contains("Windows")){return true;}return false;}}
6、@Import
@Configuration@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})// @Import导入组件,id默认是组件的全类名public class MainConfig2 {/*** 给容器中注册组件;* 1、包扫描 + 组件标注注解(@Controller/@Service/@Repository/@Component)[针对自己写的类]* 2、@Bean[导入的第三方包里面的组件]* 3、@Import[快速给容器中导入一个组件]* 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名* 2)、ImportSelector:返回需要导入的组件的全类名数组;* 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中* 4、使用Spring提供的 FactoryBean(工厂Bean);* 1)、默认获取到的是工厂bean调用getObject创建的对象* 2)、要获取工厂Bean本身,我们需要给id前面加一个&* &colorFactoryBean*/@Beanpublic ColorFactoryBean colorFactoryBean(){return new ColorFactoryBean();}}
// 自定义逻辑返回需要导入的组件public class MyImportSelector implements ImportSelector {// 返回值,就是到导入到容器中的组件全类名// AnnotationMetadata:当前标注@Import注解的类的所有注解信息@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// TODO Auto-generated method stub// importingClassMetadata// 方法不要返回null值return new String[]{"com.atguigu.bean.Blue", "com.atguigu.bean.Yellow"};}}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata:当前类的注解信息* BeanDefinitionRegistry:BeanDefinition注册类;* 把所有需要添加到容器中的bean;* 调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");if(definition && definition2){// 指定Bean定义信息;(Bean的类型,Bean。。。)RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);// 注册一个Bean,指定bean名registry.registerBeanDefinition("rainBow", beanDefinition);}}}
7、FactoryBean
@Configurationpublic class MainConfig2 {/*** 给容器中注册组件;* 1)、包扫描 + 组件标注注解(@Controller/@Service/@Repository/@Component)[针对自己写的类]* 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速给容器中导入一个组件]* 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名* 2)、ImportSelector:返回需要导入的组件的全类名数组;* 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中* 4)、使用Spring提供的 FactoryBean(工厂Bean);* 1)、默认获取到的是工厂bean调用getObject创建的对象* 2)、要获取工厂Bean本身,我们需要给id前面加一个&* &colorFactoryBean*/@Beanpublic ColorFactoryBean colorFactoryBean(){return new ColorFactoryBean();}}
// 创建一个Spring定义的FactoryBeanpublic class ColorFactoryBean implements FactoryBean<Color> {// 返回一个Color对象,这个对象会添加到容器中@Overridepublic Color getObject() throws Exception {// TODO Auto-generated method stubSystem.out.println("ColorFactoryBean...getObject...");return new Color();}@Overridepublic Class<?> getObjectType() {// TODO Auto-generated method stubreturn Color.class;}// 是单例?// true:这个bean是单实例,在容器中保存一份// false:多实例,每次获取都会创建一个新的bean;@Overridepublic boolean isSingleton() {// TODO Auto-generated method stubreturn false;}}
@Testpublic void testFactoryBean(){printBeans(applicationContext);Blue bean = applicationContext.getBean(Blue.class);System.out.println(bean);//工厂Bean获取的是调用getObject创建的对象:new Color()Object bean2 = applicationContext.getBean("colorFactoryBean");Object bean3 = applicationContext.getBean("colorFactoryBean");System.out.println("bean的类型:"+bean2.getClass());System.out.println(bean2 == bean3);// 获取ColorFactoryBean对象Object bean4 = applicationContext.getBean("&colorFactoryBean");System.out.println(bean4.getClass());}private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
二、声明周期
1、@Bean指定初始化和销毁方法
/*** bean的生命周期:* bean创建---初始化----销毁的过程* 容器管理bean的生命周期;* 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法** 构造(对象创建)* 单实例:在容器启动的时候创建对象* 多实例:在每次获取的时候创建对象** BeanPostProcessor.postProcessBeforeInitialization* 初始化:* 对象创建完成,并赋值好,调用初始化方法。。。* BeanPostProcessor.postProcessAfterInitialization* 销毁:* 单实例:容器关闭的时候* 多实例:容器不会管理这个bean;容器不会调用销毁方法;** 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,* 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization** BeanPostProcessor原理* populateBean(beanName, mbd, instanceWrapper); 给bean进行属性赋值* initializeBean* {* applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);* invokeInitMethods(beanName, wrappedBean, mbd); 执行自定义初始化* applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);*}** 1、指定初始化和销毁方法;* 通过@Bean指定init-method和destroy-method;* 2、通过让Bean实现InitializingBean:定义初始化逻辑,在创建完成bean且完成赋值后进行操作* DisposableBean:定义销毁逻辑,在容器关闭的时候进行调用;* 3、可以使用JSR250;* @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法* @PreDestroy:在容器销毁bean之前通知我们进行清理工作* 4、BeanPostProcessor【interface】:bean的后置处理器;* 在bean初始化前后进行一些处理工作;* postProcessBeforeInitialization:在任何初始化(如InitializingBean、afterPropertiesSet、initMethod等)之前工作* postProcessAfterInitialization:在任何初始化之后工作** Spring底层对 BeanPostProcessor 的使用;* bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;** @author lfy**/@ComponentScan("com.atguigu.bean")@Configurationpublic class MainConfigOfLifeCycle {// @Scope("prototype")// 指定初始化和销毁方法@Bean(initMethod="init",destroyMethod="detory")public Car car(){return new Car();}}
@Componentpublic class Car {public Car(){System.out.println("car constructor...");}public void init(){ // 初始化方法System.out.println("car ... init...");}public void detory(){ // 销毁方法System.out.println("car ... detory...");}}
2、initializeBean和DisposableBean
@Componentpublic class Cat implements InitializingBean, DisposableBean {public Cat(){System.out.println("cat constructor...");}// 销毁方法,在容器关闭的时候进行调用@Overridepublic void destroy() throws Exception {// TODO Auto-generated method stubSystem.out.println("cat...destroy...");}// 初始化方法,在创建完成bean且完成赋值后进行操作@Overridepublic void afterPropertiesSet() throws Exception {// TODO Auto-generated method stubSystem.out.println("cat...afterPropertiesSet...");}}
3、@PostConstruct和@PreDestroy
@Componentpublic class Dog {public Dog(){System.out.println("dog constructor...");}// 对象创建并赋值之后调用@PostConstructpublic void init(){System.out.println("Dog....@PostConstruct...");}// 容器移除对象之前,相当于回调通知@PreDestroypublic void detory(){System.out.println("Dog....@PreDestroy...");}}
4、BeanPostProcessor后置处理器
/*** 后置处理器:初始化前后进行处理工作* 将后置处理器加入到容器中*/@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);return bean;}}
5、BeanPostProcessor原理
6、BeanPostProcessor在Spring底层的使用
三、属性赋值
1、@Values赋值
@Datapublic class Person {// 使用@Value赋值;// 1、基本数值// 2、可以写SpEL; #{}// 3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)// @Value("zhufeng")private String name;// @Value("#{20-2}") 即@Value("18")private Integer age;// @Value("${person.nickName}")private String nickName;}
@Configurationpublic class MainConfigOfPropertyValues {@Beanpublic Person person(){return new Person();}}
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);Person person = (Person) applicationContext.getBean("person");System.out.println(person);ConfigurableEnvironment environment = applicationContext.getEnvironment();String property = environment.getProperty("person.nickName");System.out.println(property); // 输出:18applicationContext.close();
2、@PropertySource
// 使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;// 加载完外部的配置文件以后使用${}取出配置文件的值@PropertySource(value={"classpath:/person.properties"})@Configurationpublic class MainConfigOfPropertyValues {@Beanpublic Person person(){return new Person();}}
--外部配置文件person.propertiesperson.nickName=小李四
四、自动装配
1、@Autowired、@Qualifier、@Primary
/*** 自动装配;* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;** 1、@Autowired:自动注入:* 1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值* 2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找* applicationContext.getBean("bookDao")* 3)、@Qualifier("bookDao"):使用@Qualifier明确指定需要装配的组件的id,而不是使用属性名* 4)、自动装配默认一定要将属性赋值好,没有就会报错;可以使用@Autowired(required=false);* 5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;* 也可以继续使用@Qualifier指定需要装配的bean的名字* BookService{* @Autowired* BookDao bookDao; //属性名称:bookDao* }** 2、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]* @Resource:* 可以和@Autowired一样实现自动装配功能;默认是按照属性名称进行装配的;* 没有能支持@Primary功能,没有支持@Autowired(reqiured=false);* @Inject:* 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;* @Autowired是Spring定义的; @Resource、@Inject都是java规范** AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能;** 3、@Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值* 1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配* 2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取* 3)、放在参数位置:** 4、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);* 自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;* 把Spring底层一些组件注入到自定义的Bean中;* xxxAware:功能使用xxxProcessor;* ApplicationContextAware==》ApplicationContextAwareProcessor;*/@Configuration@ComponentScan({"com.atguigu.service","com.atguigu.dao","com.atguigu.controller","com.atguigu.bean"})public class MainConifgOfAutowired {@Primary@Bean(destroyMethod = "bookDao2")public BookDao bookDao(){BookDao bookDao = new BookDao();bookDao.setLable("2");return bookDao;}/*** @Bean标注的方法创建对象的时候,方法参数的值从容器中获取* @param car* @return*/@Beanpublic Color color(Car car){Color color = new Color();color.setCar(car);return color;}}
2、@Resources、@Inject
/*** 自动装配;* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;** 1、@Autowired:自动注入:* 1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值* 2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找* applicationContext.getBean("bookDao")* 3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名* 4)、自动装配默认一定要将属性赋值好,没有就会报错;* 可以使用@Autowired(required=false);* 5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;* 也可以继续使用@Qualifier指定需要装配的bean的名字* BookService{* @Autowired* BookDao bookDao;* }** 2、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]* @Resource:* 可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;* 没有能支持@Primary功能没有支持@Autowired(reqiured=false);* @Inject:* 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;* @Autowired:Spring定义的; @Resource、@Inject都是java规范** AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能;*/@Configuration@ComponentScan({"com.atguigu.service","com.atguigu.dao","com.atguigu.controller","com.atguigu.bean"})public class MainConifgOfAutowired {@Primary@Bean(destroyMethod = "bookDao2")public BookDao bookDao(){BookDao bookDao = new BookDao();bookDao.setLable("2");return bookDao;}/*** @Bean标注的方法创建对象的时候,方法参数的值从容器中获取* @param car* @return*/@Beanpublic Color color(Car car){Color color = new Color();color.setCar(car);return color;}}
3、方法、构造器位置的自动装配
/*** 自动装配;* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;** 3)、@Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值* 1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取; 默认不写@Autowired效果是一样的;都能自动装配* 2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取* 3)、放在参数位置:*/@Configuration@ComponentScan({"com.atguigu.service","com.atguigu.dao","com.atguigu.controller","com.atguigu.bean"})public class MainConifgOfAutowired {/*** @Bean标注的方法创建对象的时候,方法参数的值从容器中获取* @param car* @return*/@Beanpublic Color color(@Autowired Car car){ // 默认不写@Autowired,效果一样Color color = new Color();color.setCar(car);return color;}}
// 默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作@Componentpublic class Boss {private Car car;// 构造器要用的组件,都是从容器中获取// 如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取// @Autowiredpublic Boss(@Autowired Car car){this.car = car;System.out.println("Boss...有参构造器");}public Car getCar() {return car;}// @Autowired// 标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值;// 方法使用的参数,自定义类型的值从ioc容器中获取public void setCar(Car car) {this.car = car;}}
4、Aware注入Spring底层组件和原理
/*** 自动装配;* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;** 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);* 自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;* 把Spring底层一些组件注入到自定义的Bean中;* xxxAware:功能使用xxxProcessor;* ApplicationContextAware ==》ApplicationContextAwareProcessor;*/@Configuration@ComponentScan({"com.atguigu.service","com.atguigu.dao","com.atguigu.controller","com.atguigu.bean"})public class MainConifgOfAutowired {}
@Componentpublic class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// TODO Auto-generated method stubSystem.out.println("传入的ioc:" + applicationContext); // org.springframework.context.annotation.AnnotationConfigApplicationContext@7f560810this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {// TODO Auto-generated method stubSystem.out.println("当前bean的名字:" + name); // 输出:red}// StringValueResolver解析占位符@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {// TODO Auto-generated method stubString resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");System.out.println("解析的字符串:" + resolveStringValue); // 输出:你好Windows 10 我是360}}
5、@Profile环境搭建
/*** Profile:* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;** 开发环境、测试环境、生产环境;* 数据源:(/A)(/B)(/C);** @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件** 1、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境* 2、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效* 3、没有标注环境标识的bean在,任何环境下都是加载的;*/@PropertySource("classpath:/dbconfig.properties")@Configurationpublic class MainConfigOfProfile implements EmbeddedValueResolverAware{@Value("${db.user}")private String user;private StringValueResolver valueResolver;private String driverClass;@Beanpublic Yellow yellow(){return new Yellow();}@Profile("test")@Bean(destroyMethod = "testDataSource")public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");dataSource.setDriverClass(driverClass);return dataSource;}@Profile("dev")@Bean(destroyMethod = "devDataSource")public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_crud");dataSource.setDriverClass(driverClass);return dataSource;}@Profile("prod")@Bean(destroyMethod = "prodDataSource")public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/scw_0515");dataSource.setDriverClass(driverClass);return dataSource;}// 值解析器@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {// TODO Auto-generated method stubthis.valueResolver = resolver;// 解析db.driverClass的值driverClass = valueResolver.resolveStringValue("${db.driverClass}");}}
-- dbconfig.propertiesdb.user=rootdb.password=123456db.driverClass=com.mysql.jdbc.Driver
6、@Profile根据环境注册bean
//1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test//2、代码的方式激活某种环境;@Testpublic void test01(){//1、创建一个applicationContextAnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();//2、设置需要激活的环境applicationContext.getEnvironment().setActiveProfiles("dev");//3、注册主配置类applicationContext.register(MainConfigOfProfile.class);//4、启动刷新容器applicationContext.refresh();String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);for (String string : namesForType) {System.out.println(string);}Yellow bean = applicationContext.getBean(Yellow.class);System.out.println(bean);applicationContext.close();}
