Spring学习:Spring注解驱动开发之IOC篇

1.什么是Spring注解驱动开发?

  1.1 首先先看一下没有用注解驱动开发时,我们的spring是如何进行开发的

    Person.java

package com.usagi.annotation.bean;

public class Person {

    private int age;

    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Person() {}

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

    beans.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 class="com.usagi.annotation.bean.Person" id="person">
        <property name="age" value="12"/>
        <property name="name" value="zxg"/>
    </bean>

</beans>

    Main.java

package com.usagi.annotation;

import com.usagi.annotation.bean.Person;
import com.usagi.annotation.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person)context.getBean("person");
        System.out.print(person);
    }
}

  1.2 接下来,我们看一下spring注解驱动开发是如何写的

    MainConfig.java

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 配置类==配置文件
@Configuration // 告诉Spring这是一个配置类
public class MainConfig {

    // 给容器中注册一个Bean,类型为返回值类型,id默认是用方法名作为id
    @Bean("person01")
    public Person person(){
        return new Person(12,"lisi");
    }


}

    MainTest.java

package com.usagi.annotation;

import com.usagi.annotation.bean.Person;
import com.usagi.annotation.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {

    public static void main(String[] args) {
       ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
       Person person = (Person)context.getBean("person");
       System.out.println(person);

        String[] beanDefinitionNames = context.getBeanNamesForType(Person.class);
        for (String name: beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

2.Spring注解开发深入 

  2.1 @ComponentScan注解:Bean扫描组件

    MainConfig.java

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

// 配置类==配置文件
@Configuration // 告诉Spring这是一个配置类
@ComponentScan(value = "com.usagi",includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false)
// @ComponentScan value:指定要扫描的包
// excludeFilters Filter[]:指定扫描的时候按照什么规则排查那些组件
// includeFilters Filter[]:指定扫描的时候只需要包含哪些组件
// useDefaultFilters:指定默认的扫描规则是否有效
public class MainConfig {

    // 给容器中注册一个Bean,类型为返回值类型,id默认是用方法名作为id
    @Bean("person01")
    public Person person(){
        return new Person(12,"lisi");
    }
}

     IOCTest.java

package com.usagi.test;

import com.usagi.annotation.config.MainConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTest {

    @Test
    public void test1(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

  2.2 自定义FilterType规则

    MyTypeFilter.java

package com.usagi.annotation.config;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class MyTypeFilter implements TypeFilter {

    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        // 获取当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        // 获取当前正在扫描的类的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        // 获取当前类资源(类的路径)
        Resource resource = metadataReader.getResource();
        String className = classMetadata.getClassName();
        System.out.println("---> "+className);
        if(className.contains("Dao")){
            return true;
        }
        return false;
    }
}

    MainConfig.java

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import com.usagi.annotation.service.TestService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

// 配置类==配置文件
@Configuration // 告诉Spring这是一个配置类
@ComponentScan(value = "com.usagi",includeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
// @ComponentScan value:指定要扫描的包
// excludeFilters Filter[]:指定扫描的时候按照什么规则排查那些组件
// includeFilters Filter[]:指定扫描的时候只需要包含哪些组件
// useDefaultFilters:指定默认的扫描规则是否有效
// FilterType.ANNOTATION:按照注解
// FilterType.ASSIGNABLE_TYPE:按照给定的类型
// FilterType.ASPECTJ:使用ASPECTJ类型
// FilterType.REGEX:使用正则表达式
// FilterType.CUSTOM:自定义规则过滤
public class MainConfig {
    // 给容器中注册一个Bean,类型为返回值类型,id默认是用方法名作为id
    @Bean("person01")
    public Person person(){
        return new Person(12,"lisi");
    }

}

   2.3 @Scope:调整作用域

    MainConfig2

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig2 {

    /**
     * @Scope:调整作用域
     * prototype:多实例的:IOC容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象
     * singleton:单实例的:IOC容器启动会调用方法创建对象放到IOC容器中,以后每次获取就是直接从容器(map.get())中拿
     * request:同一个请求创建一个实例
     * session:同一个session创建一个实例
     */
    @Scope("prototype")
    @Bean("person2")
    public Person person(){
        return new Person(190,"小东西");
    }
}

  2.4 @Lazy:懒加载,容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig2 {

    /**
     * 懒加载:
     *      单实例bean:默认在容器启动的时候创建对象
     *      懒加载:容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化
     */
    @Lazy
    @Bean("person2")
    public Person person(){
        return new Person(190,"小东西");
    }
}

  2.5 @Conditional :类级别:按照一定的条件进行判断,满足条件才注册此类下的所有bean,方法级别,满足条件给容器中注册bean

    LinuxCondition.java

package com.usagi.annotation.condition;


import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {

    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        // 1.能获取到IOC使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        // 2.获取类加载器
        ClassLoader classLoader = conditionContext.getClassLoader();
        // 3.获取当前环境信息
        Environment environment = conditionContext.getEnvironment();
        // 4.获取到bean定义的注册类
        BeanDefinitionRegistry registry = conditionContext.getRegistry();
        String property = environment.getProperty("os.name");
        if(property.contains("linux")){
            return true;
        }
        return false;
    }
}

    WindowsCondition.java

package com.usagi.annotation.condition;


import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition {

    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if(property.contains("Window")){
            return true;
        }
        return false;
    }
}

    MainConfig2.java

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Person;
import com.usagi.annotation.condition.LinuxCondition;
import com.usagi.annotation.condition.WindowsCondition;
import org.springframework.context.annotation.*;

/**
 * @Conditional({Condition}):按照一定的条件进行判断,满足条件才注册此类下所有的bean
 */
@Conditional({LinuxCondition.class})
@Configuration
public class MainConfig2 {

    /**
     * 懒加载:
     *      单实例bean:默认在容器启动的时候创建对象
     *      懒加载:容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化
     */
    @Lazy
    @Bean("person2")
    public Person person(){
        return new Person(190,"小东西");
    }

    /**
     * @Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
     */
    @Conditional({LinuxCondition.class})
    @Bean("person01")
    public Person person01(){
        return new Person(12,"Linux");
    }

    @Conditional({WindowsCondition.class})
    @Bean("person02")
    public Person person02(){
        return new Person(15,"Windows");
    }
}

  2.6 @Import:导入组件

    1)导入组件,id默认是组件的全类名

package com.usagi.annotation.config;

import com.usagi.annotation.bean.Color;
import com.usagi.annotation.bean.Person;
import com.usagi.annotation.condition.LinuxCondition;
import com.usagi.annotation.condition.WindowsCondition;
import org.springframework.context.annotation.*;

/**
 * @Conditional({Condition}):按照一定的条件进行判断,满足条件才注册此类下所有的bean
 */
@Configuration
@Import(Color.class) // @Import:导入组件,id默认是组件的全类名
public class MainConfig2 {

    @Bean("person03")
    public Person person(){
        return new Person(190,"小东西");
    }

    @Bean("person01")
    public Person person01(){
        return new Person(12,"Linux");
    }

    @Bean("person02")
    public Person person02(){
        return new Person(15,"Windows");
    }
}

    2)ImportSelector: 返回需要导入的组件的全类目数组

package com.usagi.annotation.config;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.usagi.annotation.bean.Yellow","com.usagi.annotation.bean.Red"};
    }
}
package com.usagi.annotation.config;

import com.usagi.annotation.bean.Color;
import com.usagi.annotation.bean.Person;
import com.usagi.annotation.condition.LinuxCondition;
import com.usagi.annotation.condition.WindowsCondition;
import org.springframework.context.annotation.*;

/**
 * @Conditional({Condition}):按照一定的条件进行判断,满足条件才注册此类下所有的bean
 */
@Configuration
@Import({Color.class,MyImportSelector.class}) // @Import:导入组件,id默认是组件的全类名
public class MainConfig2 {

    @Bean("person03")
    public Person person(){
        return new Person(190,"小东西");
    }

    @Bean("person01")
    public Person person01(){
        return new Person(12,"Linux");
    }

    @Bean("person02")
    public Person person02(){
        return new Person(15,"Windows");
    }
}

     3)ImportBeanDefinitionRegistrar:手动注册bean到容器中

package com.usagi.annotation.config;

import com.usagi.annotation.bean.RainBow;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
        boolean red = registry.containsBeanDefinition("com.usagi.annotation.bean.Color");
        boolean yellow = registry.containsBeanDefinition("com.usagi.annotation.bean.Yellow");
        if(red && yellow){
            RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
            registry.registerBeanDefinition("rainBow",beanDefinition);
        }
    }
}
package com.usagi.annotation.config;

import com.usagi.annotation.bean.Color;
import com.usagi.annotation.bean.Person;
import com.usagi.annotation.condition.LinuxCondition;
import com.usagi.annotation.condition.WindowsCondition;
import org.springframework.context.annotation.*;

/**
 * @Conditional({Condition}):按照一定的条件进行判断,满足条件才注册此类下所有的bean
 */
@Configuration
@Import({Color.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class}) // @Import:导入组件,id默认是组件的全类名
public class MainConfig2 {

    @Bean("person03")
    public Person person(){
        return new Person(190,"小东西");
    }

    @Bean("person01")
    public Person person01(){
        return new Person(12,"Linux");
    }

    @Bean("person02")
    public Person person02(){
        return new Person(15,"Windows");
    }
}

 3.FactoryBean

  3.1 使用Spring提供的FactoryBean(工厂Bean),1)默认获取的是工厂bean调用getObject创建对象。2)要获取工厂bean本身,我们需要给id前面加一个&

package com.usagi.annotation.bean;

import org.springframework.beans.factory.FactoryBean;

public class ColorFactoryBean implements FactoryBean<Color> {

    @Override
    public Color getObject() throws Exception {
        return new Color();
    }

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    // 是单例?
    // true:这个bean是单实例,在容器中保存一份
    // false:多实例,每次创建都会创建一个新的bean
    @Override
    public boolean isSingleton() {
        return true;
    }
}
    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
    @Test
    public void test5(){
        Object obj1 = applicationContext.getBean("colorFactoryBean");
        System.out.println(obj1.getClass());
        Object bean = applicationContext.getBean("&colorFactoryBean");
        System.out.println(bean.getClass());
    }

 4.Bean的生命周期

  4.1 bean的生命周期指:bean创建->初始化->销毁的过程,bean的生命周期由容器来管理,我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁的方法

    1)通过@Bean指定init-method、destroy-method方法,初始化:对象创建完成,并赋值好,调用初始化方法,销毁:单实例:容器关闭的时候,多实例:容器不会管理这个bean

package com.usagi.annotation.bean;

public 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.....");
    }
}
package com.usagi.annotation.config;

import com.usagi.annotation.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfigOfLifeCycle {

    @Bean(initMethod = "init",destroyMethod = "detory")
    public Car car(){
        return new Car();
    }
}
package com.usagi.test;

import com.usagi.annotation.config.MainConfigOfLifeCycle;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTestLife {

    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);

    @Test
    public void test01(){
        applicationContext.close();
    }
}

    2)通过类去实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)

package com.usagi.annotation.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Cat implements InitializingBean,DisposableBean {

    public Cat() {
        System.out.println("cat ...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("cat destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("cat afterPropertiesSet...");
    }
}
    @Bean
    public Cat cat(){
        return new Cat();
    }

    3)可以使用JSR250,@PostConstruct(对象创建并赋值之后调用),@PreDestroy(容器移除对象之前调用)

package com.usagi.annotation.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class Dog {

    public Dog() {
        System.out.println("Dog constructor...");
    }

    @PostConstruct
    public void init(){
        System.out.println("Dog...@PostConstruct...");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("Dog...@PreDestroy...");
    }
}

    4)BeanPostProcessor组件:初始化前后进行处理工作,postProcessBeforeInitialization(初始化:对象创建完成,并赋值好,调用初始化方法),postProcessAfterInitialization(销毁:单例,容器关闭的时候,多实例,容器不会管理这个bean,容器不会调用销毁方法)

package com.usagi.annotation.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 后置处理器:初始化前后进行处理工作
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization:=>"+s);
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessAfterInitialization:=>"+s);
        return o;
    }
}

   4.2 @Value 为Bean赋值,1、基本数值 2、可以写SpEL,#{}3、可以写${};取出配置文件中的值(在运行环境变量里面的值)

package com.usagi.annotation.bean;

import org.springframework.beans.factory.annotation.Value;

public class Person {

    // 使用@Value赋值
    // 1、基本数值
    // 2、可以写SpEL;#{}
    // 3、可以写${}; 取出配置文件中的值(在运行环境变量里面的值)
    @Value("#{10-9}")
    private int age;

    @Value("张三")
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Person() {}

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

5.容器的自动装配

  5.1  @Autowired:自动注入

    1)默认优先按照类型去容器中找对应的组件,找到就赋值

    2)@Qualifier 指定Id,注入组件

    3)required:配置注入是否必须

package com.usagi.annotation.service;

import com.usagi.annotation.dao.TestDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @Qualifier("testDao3")
    @Autowired(required = false)
    private TestDao testDao;

    @Override
    public String toString() {
        return "TestService{" +
                "testDao=" + testDao +
                '}';
    }
}

   5.2 @Resource: 可以和 @Autowired 一样实现自动装配的功能,默认是按照组件名称进行装配的;没有支持@Primary功能没有支持@Autowired(reqiured=false)

package com.usagi.annotation.service;

import com.usagi.annotation.dao.TestDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class TestService {
    
    @Resource
    private TestDao testDao;

    @Override
    public String toString() {
        return "TestService{" +
                "testDao=" + testDao +
                '}';
    }
}

  5.3 @Inject:需要导入javax.inject的包,和 @Autowired 的功能一样

package com.usagi.annotation.service;

import com.usagi.annotation.dao.TestDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.inject.Inject;

@Service
public class TestService {

    @Inject
    private TestDao testDao;

    @Override
    public String toString() {
        return "TestService{" +
                "testDao=" + testDao +
                '}';
    }
}

总结:@Autowired 是 Spring 定义的,@Resource、@Inject 是Java规范

  5.4 @Autowired注解可以标注的地方:构造器、参数、方法、属性;

    1)标注在方法中:Spring创建当前对象,就会调用方法,完成赋值,方法使用的参数,自定义类型的值,从IOC容器中获取

    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }

    2)标注在构造器中:Spring创建对象时,就会调用完成赋值

    @Autowired
    public Boos( Car car){
        this.car = car;
    }

    3)标注在参数中,也是从IOC容器中获取值

    public Boos(@Autowired Car car){
        this.car = car;
    }

  5.5 自定义的组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory),自定义组件实现xxxAware,在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;把Spring底层一些组件注入到自定义的Bean中,xxxAware:功能使用xxxProcessor

package com.usagi.annotation.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;

@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {

    private ApplicationContext applicationContext;

    public void setBeanName(String name) {
        System.out.println(name);
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext= applicationContext;
        System.out.println(this.applicationContext);
    }

    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        String s = stringValueResolver.resolveStringValue("你好${os.name}");
        System.out.println(s);
    }
}

 6. @Profile 环境配置注解

  6.1 @Profile :指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境都注册

package com.usagi.annotation.config;


import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

@Profile("test")
@PropertySource("classpath:/jdbc.properties")
@Configuration
public class MainConfigOfProfile {

    @Value("${jdbc.username}")
    private String user;

    @Value("${jdbc.password}")
    private String password;

    @Value("${jdbc.url}")
    private String jdbcUrl;

    @Value("${jdbc.driver}")
    private String driverClass;

    @Profile("dev")
    @Bean("devDataSource")
    public DataSource dataSourceDev() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://192.168.10.244:3306/supplier_web?useUnicode=true&characterEncoding=utf8");
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }

    @Profile("test")
    @Bean("testDataSource")
    public DataSource dataSourceTest() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://192.168.10.244:3306/product_web?useUnicode=true&characterEncoding=utf8");
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }

    @Profile("pro")
    @Bean("proDataSource")
    public DataSource dataSourcePro() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://192.168.10.244:3306/top_db?useUnicode=true&characterEncoding=utf8");
        dataSource.setDriverClass(driverClass);
        return dataSource;
    }
}

 

package com.usagi.test;

import com.usagi.annotation.config.MainConfigOfProfile;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTest_Profile {

    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 1.创建一个applicationContext
        // 2.设置需要激活的环境
        applicationContext.getEnvironment().setActiveProfiles("test","dev");
        // 3.注册主配置类
        applicationContext.register(MainConfigOfProfile.class);
        // 4.启动刷新容器
        applicationContext.refresh();

        printBean(applicationContext);
    }

    private void printBean(AnnotationConfigApplicationContext applicationContext){
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name: beanDefinitionNames) {
            System.out.println(name);
        }
    }
}
posted @ 2018-07-17 21:24  东特出猫  阅读(652)  评论(0编辑  收藏  举报