• Spring注解开发系列Ⅴ --- 自动装配&Profile


    自动装配:
    spring利用依赖注入和DI完成对IOC容器中各个组件的依赖关系赋值。自动装配的优点有:
    • 自动装配可以大大地减少属性和构造器参数的指派。
    • 自动装配也可以在解析对象时更新配置。

    自动装配的方式有很多,其中包含spring的注解以及java自带的注解下面来看一看这些自动装配方式的区别

    1.@Autowired(Spring规范)

    @Autowired 在Spring2.5引入,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。
    无需再通过传统的在bean的xml文件中进行bean的注入配置。而是使用注解,系统自动为你注入,即隐式配置。@Autowired是根据类型进行标注的,如需要按照名称进行装配,则需要配合@Qualifier使用 


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

    2).若有多个相同类型的组件,再将属性名称作为组件的id去容器中查找

    3).使用@Qualifier("bookDao")来指定需要装配的组件id而不是根据属性

    4).自动装配,默认一定要属性赋值好,否则会报错,使用@Autowired(required=false)可以避免报错

    5).@Primary("bookDao2")让Spring进行自动装配时,在没有明确用@Qualifier指定的情况下默认使用优先首选的bean

    默认规则(不用写Autowired都能实现自动装配):

    1.@Autowired 可以标注在方法,有参构造,参数,spring容器创建当前对象,就会调用该方法,完成参数赋值,需要的参数从容器中获取,完成自动装配

    2.@Bean 标注的方法创建对象的时候,方法参数的值从容器中获取

    2.@Resource(JSR规范)

    可以和@Autowired一样实现自动装配,默认按照组件名称进行装配,没有支持@Qualifier和@Primary的功能

    3.@Inject(JSR规范)

    可以和@Autowired一样实现自动装配,使用时需要导入javax.inject依赖,可以支持@Qualifier和@Primary的功能,不支持require=false

     4.Awar注入Spring底层组件&原理

    自定义组件要使用spring底层的一些组件(ApplicationContext,BeanFactory),需要实现xxxAware

    在创建对象的时候,会调用接口规定的方法注入相关组件:Aware,把Spring底层一些组件注入到自定义的bean中

    xxxAware,功能使用xxxProcessor(后置处理器)完成 ApplicationContextAware=>ApplicationContextProcessor

    @Component
    public class Green implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
        private ApplicationContext applicationContext;
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            System.out.println("applicationContext:"+applicationContext);
            this.applicationContext = applicationContext;
        }
    
        @Override
        public void setBeanName(String s) { //获取当前bean的名称
            System.out.println("当前bean的名字"+s);
        }
    
        @Override
        public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) { //解析字符串的方法
            String s = stringValueResolver.resolveStringValue("你好${os.name} 我是#{10*19}");
            System.out.println("解析的字符串:"+s);
    
        }
    }

    @Profile的使用

    Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能,实际开发中,分为开发环境,测试环境,生产环境,@Profile 可以指定组件在哪个环境下才能被注册到容器中,加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中,默认是default。

    切换环境:

    1.使用命令行动态参数:在虚拟机参数位置加载-Dspring.profiles.active=test

    2.使用无参构造器切换环境

    @Profile("test")
    @PropertySource("classpath:dbconfgig.properties")
    @Configuration
    public class ProfileConfig implements EmbeddedValueResolverAware {
        @Value("${db.user}")
        private String username;
    
        private StringValueResolver valueResolver;//值解析器
        @Profile("test")
        @Bean("testDataSource")
        public DataSource dataSourceTest(@Value("${db.password}") String password) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(username); //属性中直接获取配置文件中的值
    
            comboPooledDataSource.setPassword(password); //参数中获取配置文件的值
            comboPooledDataSource.setUser("jdbc:mysql://localhost:3306/test");
            String driverClass = valueResolver.resolveStringValue("${db.driverClass}"); //使用值解析器获取配置文件中的值
            comboPooledDataSource.setDriverClass(driverClass);
            return comboPooledDataSource;
        }
        @Profile("product")
        @Bean("proDataSource")
        public DataSource dataSourceProduct(@Value("${db.password}") String password) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(username);
            comboPooledDataSource.setPassword(password);
            comboPooledDataSource.setUser("jdbc:mysql://localhost:3306/product");
            String driverClass = valueResolver.resolveStringValue("${db.driverClass}");
            comboPooledDataSource.setDriverClass(driverClass);
            return comboPooledDataSource;
        }
        @Profile("dev")
        @Bean("devDataSource")
        public DataSource dataSourceDevelop(@Value("${db.password}") String password) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(username);
            comboPooledDataSource.setPassword(password);
            comboPooledDataSource.setUser("jdbc:mysql://localhost:3306/develop");
            String driverClass = valueResolver.resolveStringValue("${db.driverClass}");
            comboPooledDataSource.setDriverClass(driverClass);
            return comboPooledDataSource;
        }
    
        @Profile("test")
        @Bean
        public Yellow yellow(){
            return new Yellow();
        }
        @Override
        public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
            this.valueResolver = stringValueResolver;
        }
    }
      @Test
        public void test02(){
            //1.创建一个application无参构造(不能使用有参构造,要自己写)
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
           //2.设置需要激活的环境
            applicationContext.getEnvironment().setActiveProfiles("test","dev");
           //3.注册主配置类
            applicationContext.register(ProfileConfig.class);
            //4.启动刷新容器
            applicationContext.refresh();
    
    
            String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
            for (String bean: beanNamesForType){
                System.out.println(bean);
            }
    
            Yellow bean = applicationContext.getBean(Yellow.class);
            System.out.println(bean);
        }

    IOC总结

    1.组件添加: 重点掌握@Condition以及@Import注解

     

  • 相关阅读:
    Keil C 里面Lib库文件的生成与调用
    关于在 KEIL C51 中嵌入汇编以及C51与A51间的相互调用
    点阵字库的生产原理(转)
    研华的数字输入/输出模块
    EQueue
    WIFI机器人网
    低成本自制航模电子设备系列(转)
    128階數的Shunt音量控制器
    LM3886-SVO純直流功率放大器
    强悍高效率 92% Nixie Tube 升压电路 12V升150-250V(转)
  • 原文地址:https://www.cnblogs.com/wangxiayun/p/10109893.html
Copyright © 2020-2023  润新知