自动装配:
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注解

Spring注解开发系列Ⅴ --- 自动装配&Profile的更多相关文章

  1. Spring注解开发系列专栏

    这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...

  2. Spring注解开发系列Ⅵ --- AOP&事务

    注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...

  3. Spring注解开发系列VIII --- SpringMVC

    SpringMVC是三层架构中的控制层部分,有过JavaWEB开发经验的同学一定很熟悉它的使用了.这边有我之前整理的SpringMVC相关的链接: 1.SpringMVC入门 2.SpringMVC进 ...

  4. Spring注解开发系列VII --- Servlet3.0

    Servlet3.0简介 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用 ...

  5. Spring注解开发系列Ⅰ--- 组件注册(上)

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...

  6. Spring注解开发系列Ⅱ --- 组件注册(下)

    1.@Import注册组件 @Import主要功能是通过导入的方式实现把实例加入springIOC容器中, /** * 给容器注册组件 * 1.包扫描+组件标注注解(@Controller,@Serv ...

  7. Spring注解开发系列Ⅲ --- 生命周期

    Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...

  8. Spring注解开发系列Ⅳ --- 属性赋值

    在Spring框架中,属性的注入我们有多种方式,我们可以通过构造方法注入,可以通过set方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象.数组.List集合.map集合.P ...

  9. Spring注解开发系列Ⅸ --- 异步请求

    一. Servlet中的异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果要处理一些 ...

随机推荐

  1. C# event 事件-2

    本次是对第一篇事件随笔的补充笔记,涉及题目依然使用上一篇的习题.上一篇地址:https://www.cnblogs.com/FavoriteMango/p/11685702.html 1.事件的定义 ...

  2. 洛谷$P1345\ [USACO5.4]$ 奶牛的电信$Telecowmunication$ 网络流

    正解:最小割 解题报告: 传送门$QwQ$ $QwQ$好久没做网络流了来复健下. 这个一看就很最小割趴?考虑咋建图?就把点拆成边权为$1$的边,然后原有的边因为不能割所以边权为$inf$. 然后跑个最 ...

  3. 分支结构,for循环,while循环,跳出循环

    #流程控制 概念:通过规定的语句让程序代码有条件的按照一定的方 式执行 顺序结构 按照书写顺序来执行,是程序中最基本的流程结构 选择结构(分支结构.条件结构) 分支结构 单路分支:if(执行的条件){ ...

  4. 「Luogu P2278」[HNOI2003]操作系统 解题报告

    题面 一道模拟题,模拟CPU的处理过程?!省选模拟题 思路: 模拟退火大法+优先队列乱搞 要注意的点 1.空闲时,CPU要处理进程 2.当队列中没有进程时,要先进行判断,然后访问 3.当优先级高的进程 ...

  5. 【DDD】持久化领域对象的方法实践

    [toc] 概述 在实践领域驱动设计(DDD)的过程中,我们会根据项目的所在领域以及需求情况捕获出一定数量的领域对象.设计得足够好的领域对象便于我们更加透彻的理解业务,方便系统后期的扩展和维护,不至于 ...

  6. electron-vue 设置cookie

    //设置登录cookie setCookie(name,value){ var Days=30; var exp=new Date(); var date=Math.round(exp.getTime ...

  7. 在idea中运行GitHub项目

    1.首先在本地建一个文件夹,比如qm 2. 在GitHub中找到你所运行项目的路径 3.在idea中[File]-->[New]--->[Project from Version Cont ...

  8. Python开发 之 Websocket 的使用示例

    1.唠唠叨叨 最近又回顾了下Websocket,发现已经忘的七七八八了.于是用js写了客户端,用python写了服务端,来复习一下这方面的知识. 2.先看一下效果吧 2.1.效果1(一个客户端连上服务 ...

  9. Spring Boot 2.X(十九):集成 mybatis-plus 高效开发

    前言 之前介绍了 SpringBoot 整合 Mybatis 实现数据库的增删改查操作,分别给出了 xml 和注解两种实现 mapper 接口的方式:虽然注解方式干掉了 xml 文件,但是使用起来并不 ...

  10. dfs 序 欧拉序

    推荐博客 :https://www.cnblogs.com/stxy-ferryman/p/7741970.html DFS序其实就是一棵树顺次访问的结点的顺序,例如下面这棵树 它的 dfs 序就是 ...