Spring (二)扫描与依赖注入

##一、包扫描
前文中配置类里显示的构造了类对象,而创建bean还有一种更为简便的方式,即包扫描,仅需在配置类上添加@ComponentScan,即可扫描当前配置文件所在包及子包下的类,将带有@Component注解的类创建并注入到Spring容器中。

package com.zdg.beanfit;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.zdg.component.ChineseController;
@Configuration
@ComponentScan("com.zdg.component")
public class ScanConfig {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = 
				new AnnotationConfigApplicationContext(ScanConfig.class);
		System.out.println(context.getBean("p"));
		System.out.println(context.getBean(ChineseController.class));
		
		context.close();
	}
}

这里@ComponentScan中定义了包位置,则会去扫描指定的包,包中的类也需要添加相应的注解来控制是否创建对象。可选的注解有@Component、@Controller、@Service、@Repository,这些注解名称不同,实际仅是为了标明类的功能类型,本质上都是Component。如@Controller注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

可以看到该注解上使用了@Component注解,其余几个也是一样,另外value属性用于标明bean的id即bean的名称。
##二、依赖注入
依赖注入可以使用@Autowired注解,该注解可以声明在方法、属性或是构造函数上:

@Component
public class Person {
	private Pet pet;
	@Autowired
	public void setPet(Pet pet) {
		this.pet = pet;
	}
	public Pet getPet() {
		return pet;
	}
}

以上代码声明了一个宠物对象,Pet是一个接口,仅声明了一个print函数,另外创建了一个实现类:

@Component
public class Pig implements Pet{

	public void print() {
		System.out.println(this);
	}

}

此时Spring容器会将容器中的Pig注入到Person中:

@Configuration
@ComponentScan("com.zdg.component")
public class ScanConfig {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = 
				new AnnotationConfigApplicationContext(ScanConfig.class);
		Person p = context.getBean(Person.class);
		p.getPet().print();//com.zdg.component.Pig@345965f2
		context.close();
	}
}

运行后打印值如代中的注释相同,如此便完成了一个简单的依赖注入,而整个过程并未显示调用new关键字创建对象,也没有调用任何set方法注入值,整个过程由Spring容器自动完成。
##三、指定注入
上面的代码中Pet的实现类仅有一个,如果再加一个Cat实现类,那注入时会选择哪一个呢,Spring也不知道,因此需要我们指定一个bean注入,这里有三种方法实现:
1、@Primary
在组件上添加@Primary注解,在注入时若有多个可选对象,则会在注入时优先选择该类注入:

@Component
@Primary
public class Pig implements Pet{
	public void print() {
		System.out.println(this);
	}
}

2、@Qualifier
使用该注解可以显示指定一个bean注入,此时存在@Primary注解也会注入@Qualifier指定的bean(@Primary仅在未指定注入对象时优先选用)

@Component()
public class Person {
	private Pet pet;
	@Autowired
	@Qualifier("cat")
	public void setPet(Pet pet) {
		this.pet = pet;
	}
	public Pet getPet() {
		return pet;
	}
}

3、自定义注解:
除了@Qualifier外,还可以自定义注解实现指定bean注入,注解定义如下:

@Target({ElementType.FIELD, ElementType.METHOD, 
	ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface PetCat {
}

只需添加@Qualifier注解,另外两个注解从Qualifier注解中复制过来即可。
使用方式:
第一步,在组件定义上添加自定义注解

@Component
@PetCat
public class Cat implements Pet {
	public void print() {
		System.out.println(this);
	}
}

第二步,在自动注入的函数上添加自定义注解:

@Component()
public class Person {
	private Pet pet;
	@Autowired
	@PetCat
	public void setPet(Pet pet) {
		this.pet = pet;
	}
	public Pet getPet() {
		return pet;
	}
}

这样在Spring选择注入对象时就会选择我们指定的bean了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值