博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring注解 之自动装配@Autowired、@Resource
阅读量:2456 次
发布时间:2019-05-10

本文共 6758 字,大约阅读时间需要 22 分钟。

文章目录

自动装配:
Spring利用依赖注入( Dependency Injection,DI )。,完成对IOC容器中中各个组件的依赖关系赋值。

@Autowired:(Spring规范支持的注解)

  • 默认优先按照类型去容器中找对应的组件applicationContext.getBean(BookDao.class)找到就赋值
  • 如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找(applicationContext.getBean("bookDao"))
  • @Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
  • 自动装配默认一定要将属性赋值好,没有就会报错;可以使用@Autowired(required=false)
  • @Primary:让Spring进行自动装配的时候,默认使用首选的bean;也可以继续使用@Qualifier指定需要装配的bean的名字,@Qualifier优先级高于@Primary

@Resource(JSR250)和@Inject(JSR330)[java规范的注解]

  • @Resource可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
  • @Resource(name=“XXX”)指定名称进行装配
  • @Inject需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;

@Autowired:Spring定义的;

@Resource、@Inject都是java规范;

  • AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能;

UserDao

@Repository@Getter@Setter@ToStringpublic class UserDao {
private String lable = "1";}

UserService

import lombok.ToString;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service@ToStringpublic class UserService {
@Qualifier("userDao") @Autowired(required = false) private UserDao userDao; @Resource private UserDao userDao;}

Spring配置文件Config.java

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;@Configuration@ComponentScan("com.example.demo")public class Config {
@Primary @Bean("userDao2") public UserDao userDao(){
UserDao userDao = new UserDao(); userDao.setLable("2"); return userDao; }}

测试类

import org.junit.Test;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class IOCTest {
@Test public void test01(){
// 创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); UserService bean = applicationContext.getBean(UserService.class); System.out.println(bean); // 关闭容器 applicationContext.close(); }}

@Autowired可以标注在构造器,参数,方法,属性上;都是从容器中获取参数组件的值

  • [标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
  • [标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
  • 放在参数位置:

使用方法自动装配。

// 默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作@Service@ToStringpublic class UserService {
private UserDao userDao; //标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值; //方法使用的参数,自定义类型的值从ioc容器中获取 @Autowired public void setUserDao(UserDao userDao) {
this.userDao = userDao; }}

使用构造器自动装配。

@Service、@Component注解,Spring容器会自动调用无参构造器。

// 默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作@Service@ToStringpublic class UserService {
private UserDao userDao; // 构造器上的参数对象从容器中获取 @Autowired UserService(UserDao userDao){
this.userDao = userDao; } // 或者 UserService(@Autowired UserDao userDao){
this.userDao = userDao; }}

Aware注入Spring底层组件&原理

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);

自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
把Spring底层一些组件注入到自定义的Bean中;
xxxAware:功能使用xxxProcessor;
ApplicationContextAware==》ApplicationContextAwareProcessor;

配置类:

package com.example.demo;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan("com.example.demo")public class Config {
}

自定义组件:

package com.example.demo;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@ToStringpublic class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext; } @Override public void setBeanName(String name) {
System.out.println("当前bean的名字:"+name); } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) {
String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}"); System.out.println("解析的字符串:"+resolveStringValue); }}

测试类:

@Testpublic void test01(){
// 创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); Red bean = applicationContext.getBean(Red.class); System.out.println(bean); // 关闭容器 applicationContext.close();}

@Profile根据环境注册bean

/** * Profile: * 		Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能; *  * 开发环境、测试环境、生产环境; * 数据源:(/A)(/B)(/C); *  *  * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件 *  * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境 * 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效 * 3)、没有标注环境标识的bean在,任何环境下都是加载的; */

配置类:

import com.mchange.v2.c3p0.ComboPooledDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import javax.sql.DataSource;@Configurationpublic class Config {
@Profile("test") @Bean public DataSource dataSourceTest(){
DataSource dataSource = new ComboPooledDataSource(); return dataSource; } @Profile("dev") @Bean public DataSource dataSourceDev(){
DataSource dataSource = new ComboPooledDataSource(); return dataSource; }}

测试类:

1、使用命令行动态参数: 在虚拟机参数位置加载-Dspring.profiles.active=test
在这里插入图片描述

@Test  public void test01() {
// 创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); String[] beans = applicationContext.getBeanNamesForType(DataSource.class); for (String bean : beans) {
System.out.println(bean); } // 关闭容器 applicationContext.close(); }

2、代码的方式激活某种环境;

@Test  public void test01() {
// 创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); // 1、创建一个applicationContext // 2、设置需要激活的环境 applicationContext.getEnvironment().setActiveProfiles("dev"); // 3、注册主配置类 applicationContext.register(Config.class); // 4、启动刷新容器 applicationContext.refresh(); String[] beans = applicationContext.getBeanNamesForType(DataSource.class); for (String bean : beans) {
System.out.println(bean); } // 关闭容器 applicationContext.close(); }

转载地址:http://cgdhb.baihongyu.com/

你可能感兴趣的文章
c专家编程/c陷阱_如何避免常见的初学者陷阱并像专家一样开始编码
查看>>
ruby on rails_我成为了Ruby on Rails和React的贡献者,你也可以
查看>>
React模式:集中式PropTypes
查看>>
esp freertos_如何开始使用FreeRTOS和ESP8266
查看>>
玻璃上的编码喜悦(+ 10史诗般的Epigrams)
查看>>
classlist使用方法_如何通过使用HTML5的classList API在没有jQuery的情况下操作类
查看>>
openstack文档_八分钟的升级,激发了文档贡献,以及更多的OpenStack新闻
查看>>
Google发布了SwiftShader,Linux上的Spatials更新以及更多游戏新闻
查看>>
openstack项目_新项目,安全性以及更多OpenStack新闻
查看>>
openstack安全_查找安全问题,区域性事件以及更多OpenStack新闻
查看>>
搭建openstack错误_错误粉碎,生日庆祝活动以及更多OpenStack新闻
查看>>
美国正在丢掉非洲数字市场_即插即用服务器可访问非洲数百万个数字文档
查看>>
android 象棋开源_7种面向国际象棋玩家的开源Android应用
查看>>
使用PatternFly解决用户体验问题
查看>>
openstack做安卓_我们是我们为OpenStack做出的贡献
查看>>
开源字体_开源努力使土著语言成为正式字体
查看>>
php面向对象开源_7个面向学生的开源游戏
查看>>
foss测试_防止下一次心脏出血,使FOSS更安全
查看>>
开放经济的宏观经济学答案_从开放的角度回答管理问题的8个答案
查看>>
drupal 页面分栏_使用段落在Drupal中构建更好的页面
查看>>