Spring学习02--Spring中Bean的声明与装配

Spring的核心是Spring容器,容器负责管理应用中的组件的生命周期,它负责创建这些组件的创建(bean)和依赖管理

spring配置bean的可选方案有三种:

  1. 在XML中进行显示配置
<bean id="math" class="xxx.Math"/><!--必须使用全限定的类名-->
<bean id="College" class="xxx.CollegeStudent">
	<constructor-arg ref="math"/>
</bean>

如上,是XML常见配置,College通过构造方法装配Math。当遇到构造方法参数包含集合类的时候该怎么处理呢,例public SSStudent(String author,int score,List titles){…};

<bean id="ssstudent" class="xxxx.SssStudent" >
	<constructor-arg value="李老师"/>
	<constructor-arg value=100/>
	<constructor-arg >
		<list>
			<ref bean ="oneChoseTitle"/>
			<ref bean ="multiChoseTitle"/>
			...
		</list>
	</constructor-arg >
</bean>

XML除了利用构造方法装配bean,还可以通过set方法

public class JStudent implements Student{
	private Subject subject;
}
//...省略get/set方法

Jstudent除了默认构造器没有任何构造器,当我们通过XML作如下配置

<bean id="jstudent" class="xxx.JStudent"/>

上面的配置在Spring创建bean时没有任何问题,但是当它调用exam方法时会出现NULLPOINTEREXCEPTION,因为并没有注入Subject属性。下面我们作如下修改:

<bean id="jstudent" class="xxx.JStudent">
	<property name="subject" ref="math"/>
</bean>

修改后的代码,通过set方法将Subject注入了Student中。
2. 在Java中进行显示配置
通常情况下Spring推荐通过组件扫描和自动装配实现Spring的自动化配置,但是在没写场景下比如,要讲第三方库的组件装配到应用中,这种情况下是无法在它的类上添加@Component和@Autowired注解的,这个时候就可以使用显示的装配(XML/Java)。因为Java显示配置更强大、类型安全并且对重构友好,我们选择显示的Java配置

@Configuration
@ComponentScan
public class StudentConfig{
}

如上所见虽然JavaConfig配置也是用Java类,但它与一般Java类还是有区别的,它不包含任何业务逻辑,也不侵入到任何业务逻辑代码中,一般为了区分都会放到单独包中。下面我们看一下,JavaConfig是如何声明bean的

@Bean
public Subject math(){
	return new Math();
}

@Bean注解会通知Spring这个方法将产生一个bean对象,默认名字是math,如果需要制定name的话可以这样

@Bean(name="mathSubject")//指定bean的name
public Subject math(){
	return new Math();
}

下面我们来声明一个Student类依赖于Subject

public class CollegeStudent implents Student(){
	private Subject subject;
	public CollegeStudent(Subject subject){
		this.subject = subject;
	}
	public void exam(){
		subject.examination();
	}
}

显然ColledgeStudent类依赖于Subject类,接下来通过JavaConfig来实现bean之间依赖关系的维护

@Bean
public ColledgeStudent student(Subject subject){
	return new ColledgeStudent(subject);
}

这里CollegeStudent请求一个Subject类作为参数,Spring创建CollegeStudent时候,会传入一个Subject到配置方法中。
3. 隐式的bean发现机制和自动装配
spring通过两个角度来描述自动化装配
1. 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean
2.自动装配(autowiring):Spring自动满足bean之间的依赖关系
示例:

public interface Subject(){
	void examination();
}

Subject是一个科目接口类,它定义了操作考试examination,它将学生的任意实现和考试本身的耦合降到了最小,现在我们来创建一个Subject的实现:

@Component
public class Math implements Subject{
	private author="张老师";
	private int totalScore = 100;
	public void examination(){
		System.out.println("出卷人:"+author+"--总分:"+score);
	}
}

如上所述Subject实现Math,内容不重要,该类使用了@Component注解,表示该类将作为组件类,并让Spring为这个类创建bean,不过组件扫描默认是不启用的,需要显示配置Spring,让其寻找导游@Component的类并创建bean。如下:

@Configuration
@ComponentScan(basePackages="xxx")//指定扫描路径,可以为复数@ComponentScan(basePackages={"xxx","yyy"})  默认为同包下
public class StudentConfig{}

上面就是一个通过Java类进行显示配置的文件。@Component会启动Spring的组件扫描功能,并默认扫描该文件同一包下的所有子包,查找带有@Component注解的类,并创建bean。可以看到上面例子里包路径指定类型为String类型,但这种方法其实是类型不安全的(not-type-safe),如果你重构代码的话,指定的基础包会出现错误。所以我们还可以通过指定扫描对象为包中所含的类或接口

<@ComponentScan(basePakages={xxxx.class,yyyy.class})>//通过包中类或接口指定扫描范围

除了通过上面的方式还可以通过XML文件来启动组件扫描

<context:component-scan base-pakage=""/>

在base-pakage中写入需要扫描的包位置即可。
下面我们通过为bean添加注解实现自动装配

@Component
public class CollegeStudent implenents Student{
	private Subject subject;
	@Autowired
	public CollegeStudent(Subject subject){
	this.subject = subject;
	}
	public void exam(){
	subject.examination();
}
}

如上诉代码所示@Autowired注解在构造器上,从而Spring容器在创建CollegeStudent的bean对象的时候会调用其构造方法传入一个Subject类型的bean对象。当然也可以通过set方法装配

@Autowired
public void setSubject(Subject subject){
	this.subject = subject;
}

实际上任何一个满足条件的方法都可以装配bean,例如我们创建一个insetSubject方法

@Autowired
public void insertSubject(Subject subject){
	this.subject = subject;
}

上面都是孤立的使用单一方法进行bean的装配,实际上Spring中各种装配bean的方法不是互斥的,它们可以混合使用,以便开发人员根据实际情况合理设计。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值