@primary注解_Spring注解驱动开发之十——@Resource、@Inject 自动注入、Aware接口、@Profile环境配置...

57e6b96f647830dfd1beec0a3264840b.png

本文包含以下内容:

  1. @Resource、@Inject 自动注入

  2. @Autowired标注方法、构造器、参数

  3. 实现Aware 获得Spring 的底层组件

  4. 通过@Profile配置不同的环境

1.@Resource、@Inject 自动注入

1)通过 @Resource 进行Bean 注入到容器 @Resource 为 JSR250 规范中提出的,可以实现@Autowired 一样的自动装配的功能,但是, 不支持@Primary ,默认优先注入和@Autowired(reqiured=false) 运行不注入2个功能,下面开始测试:修改bookService 中,在开启bookDao2 和 @Repository 的前提下,
@Resourceprivate BookDao bookDao;
测试结果1,不设置指定的Bean id: ,默认注入了 @Repository 的Bean, 注入了lable 为2 的Bean

37bbbf078f699e866549562b73fce9aa.png

可以在里面指定注入Bean 的id ,如下代码所示:
@Resource(name="bookDao2")private BookDao bookDao;
测试结果2 , 指定注入Bean 的id ,注入了lable 为2的Bean:

b625f4f056d4859fce4f343298642516.png

2)通过@Inject  注入到容器 @Inject 是 JSR330 规范中的注解,功能跟@Autowired 功能一致,不过需要额外引入 javax.inject 依赖 引入依赖:
<dependency>  <groupId>javax.injectgroupId>  <artifactId>javax.injectartifactId>  <version>1version>dependency>
修改BookService 中的引入
@Injectprivate BookDao bookDao;
获得测试结果,成功注入lable 为1 的Bean

b75e054e12ca6e82a8ae465d40b0b8ec.png

添加 @Primary 指定lable 为2 的Bean 为优先注入,即可获得如下结果:
@Primary@Bean("bookDao2")public BookDao bookDao(){  BookDao bookDao = new BookDao();  bookDao.setLable("2");  return bookDao;}

3cbcef88259bfce0a63e0bde87458715.png

2.@Autowired标注方法、构造器、参数

除了上篇文章中的@Autowired 使用方法,@Autowired 还可以标注在 方法、构造器、参数上,进行注入,下面将进行测试建立创建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...");  }}
在Boss 中引入Car
//默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作@Componentpublic class Boss {  private Car car;}
1)标注在 方法上:
   @Autowired  public void setCar(Car car) {    this.car = car;  }
编辑测试方法
Boss boss = applicationContext.getBean(Boss.class);System.out.println(boss);Car car = applicationContext.getBean(Car.class);System.out.println(car);
获得测试结果,可以看到容器内的Car 和Boss 上的Car 是指向同一个内存地址,即同一个对象。

8f07606e159a4c6e9339c47c51d39cb9.png

2)标注在 构造器、参数上方式一:自动忽略不填写(只有一个构造方法且为有参的)
public Boss(Car car){  this.car = car;  System.out.println("Boss...有参构造器");}
方式二:加在参数上
public Boss(@Autowired Car car){  this.car = car;  System.out.println("Boss...有参构造器");}
方式三:加在构造方法上
@Autowiredpublic Boss(Car car){  this.car = car;  System.out.println("Boss...有参构造器");}
上面3种方式,测试结果如下:都会自动注入容器中的Car,可以看到内存地址 一致

ee26e91e920785a4ada10987072a098c.png

3)配合 @B ea n标注在 有参的构造 ,可以方式一:省略参数上的@Autowired
@Beanpublic Color color(Car car){  Color color = new Color();  color.setCar(car);  return color;}
方式二:不省略的情况
@Bean  public Color color(@Autowired Car car){    Color color = new Color();    color.setCar(car);    return color;  }
添加测试方法
Color color = applicationContext.getBean(Color.class);System.out.println(color);System.out.println(applicationContext);applicationContext.close();
获得测试结果如下,可以看到Color 中的Car 跟容器的的Car 是一致的

50adf78e8b3a17b3be8233608d09f482.png

3.实现Aware 获得Spring 的底层组件

Spring 中可以通过实现 XXXAware 接口,实现对应的方法,可以获取到Spring 底层的一下 组件,下面将对Aware 接口进行测试:查看源码描述:

76061262d11a80b439052a2d26fec888.png

可以看到:

Marker superinterface indicating that a bean is eligible to be notified by the Spring container of a particular framework object through a callback-style method.

spring 框架会通过 回调方法。下面以 ApplicationContextAware 、BeanNameAware 、EmbeddedValueResolverAware 为例测试 1.)ApplicationContextAware 实现setApplicationContext 获取到 ioc 容器
@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  // TODO Auto-generated method stub  System.out.println("传入的ioc:"+applicationContext);  this.applicationContext = applicationContext;}
2.)  BeanNameAware 获取到当前 容器的名称
@Overridepublic void setBeanName(String name) {  // TODO Auto-generated method stub  System.out.println("当前bean的名字:"+name);}
3.) EmbeddedValueResolverAware  获取到 字符串解析器 ,既可以跟@Value 中一样可以解析基本类型、#{} 、${} 等
@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {  // TODO Auto-generated method stub  String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");  System.out.println("解析的字符串:"+resolveStringValue);}
获得测试结果如下:

e7b554de6ad34c167fe6397b21ed75e9.png

4.通过@Profile配置不同的环境

在Spring 中,可以通过@Profile 指定 当前运行环境,如项目开发中的流程 开发、测试、生产的环境,采用不同的 配置文件等信息,如数据库文件目录等信息。下面开始测试:1.)添加数据库依赖,和c3p0 依赖
<dependency>  <groupId>c3p0groupId>  <artifactId>c3p0artifactId>  <version>0.9.1.2version>dependency><dependency>  <groupId>mysqlgroupId>  <artifactId>mysql-connector-javaartifactId>  <version>5.1.44version>dependency>
2.)建立配置文件 dbconfig.properties
db.user=rootdb.password=123456db.driverClass=com.mysql.jdbc.Driver
3.)建立新的配置类, 引入配置文件
@PropertySource("classpath:/dbconfig.properties")@Configurationpublic class MainConfigOfProfile implements EmbeddedValueResolverAware{    @Value("${db.user}")  private String user;    private String  driverClass;    @Override  public void setEmbeddedValueResolver(StringValueResolver resolver) {    // TODO Auto-generated method stub    driverClass = resolver.resolveStringValue("${db.driverClass}");  }}
4.)建立配置类Bean 
@Bean("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;}@Bean("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;  }  @Bean("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;}
5.)建立测试方法,
public class IOCTest_Profile {  //1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test  //2、代码的方式激活某种环境;  @Test  public void test01(){   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);    String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);    for (String string : namesForType) {      System.out.println(string);    }  }}
7.)可以看到运行结果如下,没有配置任何的环境, 所有Bean 都会注入进来 eba0e9f40b09ecfb4186bc6ef959acea.png8.)在对应的Bean 上加上指定环境的注解
@Profile("test")@Bean("testDataSource")@Profile("dev")@Bean("devDataSource")@Profile("prod")@Bean("prodDataSource")
9.)运行可以看到, 没有注册任何的Bean

40de86452e070e71994e36f2fe4c31f6.png

10.) 使用default ,会默认创建该Bean 跟不标注 @Profile的效果是一致的
@Profile("default")@Bean("devDataSource")
11.)获得测试结果

ea786af2bf9ebdca4e3adad0694238f9.png

12.)修改当前生效环境有 2种方式方式一:通过启动添加 JVM 启动参数
-Dspring.profiles.active=test
方式二,通过代码形式,注册容器时,不使用带参数的 构造方法进行注册
AnnotationConfigApplicationContext applicationContext =    new AnnotationConfigApplicationContext();//1、创建一个applicationContext//2、设置需要激活的环境applicationContext.getEnvironment().setActiveProfiles("dev");//3、注册主配置类applicationContext.register(MainConfigOfProfile.class);//4、启动刷新容器applicationContext.refresh();
测试结果如下,也能获取到 指定环境的值

5db6d4d36164ad827848a0af826a71ad.png

-END-

9958b93e4523679a023f0e752ec2df4a.png

可以关注我的公众号,免费获取价值1980元学习资料

点击“在看”,学多少都不会忘~

562e34caeeb7857781ccea182e9a8e60.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值