Spring注解开发——4. 核心容器(自动装配)

1. @Autowired——自动注入

1.1 属性的自动装配

        该注解在开发中使用的太多了,就不举例说了,我们只需要知道该注解默认是按照类型去容器中查找对应的组件的,如果找到有多个相同类型的组件,在将属性名作为组件的id去容器中查找。所以,如果有多个相同类型的组件存在的话,属性名就不能随便写了。这时候,如果希望可以根据属性名查找的话,可以加上另一个注解@Qualifier("属性名")来指定需要装配的组件。

注意:自动装配默认一定要将属性赋值好,没有就会报错。如果希望没有赋值好也不会报错的话,该怎么办了?可以在Autowired上加属性required,例如:@Autowired(required = false)

1.2 方法、构造器、参数位置上的自动装配

       @Autowired自动装配不仅可以用于属性上,还可以用于方法、构造器和参数上,作用都是一样的,都是将IOC容器中的对象赋值给组件。

例如:

 

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

2)构造器上:默认情况下,IOC容器启动的时候会调用无参构造器创建对象,然后进行初始化赋值等操作,我们可以在组件中定义一个有参数的构造函数(这时候如果不指定无参构造器,那么该组件中就没有无参构造器了),在构造器上加上注解@Autowired,那么IOC容器在启动的时候,就会调用该有参构造器完成对象的创建与初始化操作。

3)参数上:效果和上两种一样,如果注解位于构造器的参数上,如果只有一个参数,那么可以省略该注解,但是,@Autowired需要位于set方法上,将IOC容器中的对象注入到该组件中,否则,得到的属性值为null。

注意:这三种方式所能达到的效果是一样的,所以,只需要在组件中使用其中一种即可。

1.3 @Bean方法上的@Autowired

        我们同样可以在@Bean标注的配置方法上标注@Autowired,用于属性的赋值,例如:

当然,该注解也可以省略,因为只有一个参数。 

2. @Resource

        JSR250规范定义的注解,默认按照属性名作为组件名称,当然,该注解可以加载指定name的属性值,该注解是JAVA规范,所以功能上要弱与@Autowired,不支持@Primary,也没有required。

3. @Inject

        JSR330规范定义的注解,使用该注解需要添加对应的pom坐标

<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

注意:

1. 该注解支持@Primary功能

2. @Primary注解的作用是当容器中有相同类型的组件的时候,使用该注解标注的注解为主要组件,优先使用该注解标注的组件。

4. Aware注入Spring底层组件

        自定义组件想要使用Spring容器底层的一些组件(ApplicationContext、BeanFactory等),可以通过实现XXXAware接口,在创建对象的时候,会调用接口规定的方法注入相关组件,Aware会把spring底层一些组件注入到自定义的Bean中,xxxAware实现原理是使用了spring的后置处理器xxxProcessor,后置处理器在前面介绍过,这里不做介绍。

例如:

@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
	
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("传入的ioc:"+applicationContext);
		this.applicationContext = applicationContext;
	}

	@Override
	public void setBeanName(String name) {
		// TODO Auto-generated method stub
		System.out.println("当前bean的名字:"+name);
	}

	@Override
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
		// TODO Auto-generated method stub
		String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
		System.out.println("解析的字符串:"+resolveStringValue);
	}




}

5. @Profile

        是Spring为我们提供的可以根据当前环境动态的激活和切换一系列Bean(组件)的功能。使用@Profile注解,我们可以在不改变代码的情况下,随意的切换不同的环境

5.1 环境搭建

@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
	
	@Value("${db.user}")
	private String user;
	
	private StringValueResolver valueResolver;
	private String  driverClass;
	
	@Bean
	public Yellow yellow(){
		return new Yellow();
	}
	
	@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;
	}

	@Override
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
		this.valueResolver = resolver;
		driverClass = valueResolver.resolveStringValue("${db.driverClass}");
	}

}

注意:这个配置文件,我们一般只使用一种获取值的方式即可,这里使用了三种方式,是为了练习一下前面讲过的内容。

5.2 环境注册

        前面准备了三套环境,现在看看如何根据不同的环境使用不同的数据源。

操作步骤:

1)给每一个数据源添加@Profile

注意:加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境

2)激活方式:

2.1 使用命令参数

        在运行的时候,在JVM参数位置加载  -Dspring.profiles.active="环境参数",例如;

2.2 使用代码方式

        这时候,创建IOC容器的时候,不能使用有参构造器了,需要使用无参构造器。

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

注意:@Profile也可以作用于配置类上,这时候只有运行指定的运行环境,整个配置才能生效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值