Spring Bean的装配方式

Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring
容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解IAnnotation的装配和
自动装配
等(其中最常用的是基于注解的装配)。

1.基于XML的装配
Spring提供了两种基于XML的装配方式:设值注入( Setter Injection) 和构造注入( Constructor Injection )。
在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter方法来注入属性值。因此,设值注入要求一个Bean必须满足以下两点要求。
●Bean类必须提供一个默认的无参构造方法。
●Bean类必须为需要注入的属性提供对应的setter方法。
使用设值注入时,在Spring配置文件中,需要使用元素的子元素来为每个属性注入值;
使用构造注入时,在配置文件里,需要使用元素的子元素<constructor- -arg>来定义构造方法的参数,可以使用其value属性(或子元素)来设置该参数的值。

User.java

package com.wz.assemble.xml;
import java.util.List;
public class User {
	private String username;
	private Integer password;
	private List<String> books;
/*
 * 无参数构造函数
 * 使用设值注入必须提供 1.默认的无参数构造函数 2.为所有的属性提供setter方法
 */
		public User(){
			super();
		}
		public void setUsername(String username) {
			this.username = username;
		}
		public void setPassword(Integer password) {
			this.password = password;
		}
		public void setBooks(List<String> books) {
			this.books = books;
		}
		@Override
		public String toString() {
			return "User [username=" + username + ", password=" + password
					+ ", books=" + books + "]";
		}
		/*
		 * 全参数构造方法
		 * 使用构造注入必须提供带所有参数的构造方法
		 */
		public User(String username,Integer password,List<String> books){
			super();
			this.username = username;
			this.password = password;
			this.books = books;
		}
	}

由于要使用构造注入,所以需要其有参和无参的构造方法。同时,为了输出时能够看到结果,还重写了其属性的toString()方法。

beans5.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
 	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
		<!--1.使用设值注入方式装配User实例 -->
	<bean id="user1" class="com.wz.assemble.xml.User">
		<!-- 注入用户名 -->
		<property name="username" value="张三"></property>
		<!-- 注入口令 -->
		<property name="password" value="321"></property>
		<!-- 注入list集合 -->
		<property name="books">
			<list>
			<value>java</value>
			<value>c++</value>
			<value>Python</value>
			</list>
		</property>
	</bean>
		<!--2.使用构造注入方式装配User实例 -->
	<bean id="user2" class="com.wz.assemble.xml.User">
		<constructor-arg index="0" value="李四" />
		<constructor-arg index="1" value="123559" />
		<constructor-arg index="2">
			<list>
				<value>MySQL</value>
				<value>oracle</value>
				<value>Redis</value>
			</list>
		</constructor-arg>
	</bean>
</beans>

在上述配置文件中,<constructor- -arg >元素用于定义构造方法的参数,其属性index表示其索引(从0开始),value属性用于设置注入的值,其子元素来为User类中对应的list集合属性注入值。然后又使用了设值注入方式装配User类的实例,其中元素用于调用Bean实例中的setter方法完成属性赋值,从而完成依赖注入,而其子元素同样是为User类中对应的list集合属性注入值。

XmlBeanAssembleTest.java

package com.wz.assemble.xml;
/*
 * bean 的基于XML装配方式;设置注入和构造注入案例
 * @auther zhushiji
 */

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class XmlBeanAssembleTest {
	public static void main(String[] args) {
		// 定义配置文件路径
		String xmlPath = "com/wz/assemble/xml/beans5.xml";
		// 加载配置文件
		ApplicationContext applicationContext = 
						new ClassPathXmlApplicationContext(xmlPath);
		// 设值方式输出结果
		System.out.println(applicationContext.getBean("user1"));
		// 构造方式输出结果
		System.out.println(applicationContext.getBean("user2"));
	}
}

2.基于Annotation的装配
在Spring中,尽管使用XML配置文件可以实现Bean的装配工作,但如果应用中有很多Bean
时,会导致XML配置文件过于臃肿,给后续的维护和升级工作带来一定的困难。 为此,Spring
提供了对Annotation (注解)技术的全面支持。
Spring中定义了一系列的注解,常用的注解如下所示。
●@Component:可以使用此注解描述Spring中的Bean,但它是一一个泛化的概念, 仅仅表示一个组件( Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
●@Repository: 用于将数据访问层(DAO层)的类标识为Spring 中的Bean, 其功能与@Component相同。
●@Service: 通常作用在业务层( Service层),用于将业务层的类标识为Spring中的Bean,
其功能与@Component相同。
●@Controller: 通常作用在控制层(如Spring MVC的Controller ),用于将控制层的类标识
为Spring中的Bean,其功能与@Component相同。
●@Autowired:用于对Bean的属性变量、属性的setter 方法及构造方法进行标注,配合对
应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配。
●@Resource: 其作用与Autowired -样。其区别在于@Autowired默认按照Bean类型装配,而@Resource 默认按照Bean实例名称进行装配。@Resource 中有两个重要属性: name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。

UserDao.java

package com.wz.assemble.annotation;
public interface UserDao
	{
		public void save();
	}

UserDaoImpl.java

package com.wz.assemble.annotation;
import org.springframework.stereotype.Repository;;

@Repository("userDao")
/*
 * @Repository用于将数据访问层(DAO层)的类标识为Bean。其写法相当于配置文件
中<bean id="userDao" class="com.wz. assemble.annotation.UserDaolmpl"/>
 */
public class UserDaoImpl implements UserDao{
		public void save()
		{
			System.out.println("DAO层...save...");
		}
	
}

首先使用@Repository注解将UserDaolmpl类标识为Spring中的Bean,其写法相当于配置文件中<bean id='userDao" class=“com.itheima annotation.UserDaolmpl”/>的编写。然后在save()方法中输出打印一句话,用于验证是否成功调用了该方法。

UserService.java

package com.wz.assemble.annotation;
public interface UserService {
		public void save();
}

UserServiceImpl.java

package com.wz.assemble.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

@Service("userService")
/*
 *	@Service用于将业务层(Service 层)的类标识为Spring中的Bean。其写法相当于配置
文件中<bean id="userService" class="com.wz. assemble.annotation.UserServicelmpl"/>
	然后使用@Resource注解标注在属性userDao. 上,相当于配置文件中<property
name="userDao" ref="userDao"/>的写法
 */
public class UserServiceImpl implements UserService{
	@Resource(name="userDao")
	private UserDao userDao;
	
	public void save(){
		//调用userDao中的save方法
		this.userDao.save();
		System.out.println("Service层....save...");		
	}

}

首先使用@Service注解将UserServicelmpl类标识为Spring中的Bean,这相当于配置文件中<bean id=“userService” class="com.itheima annotation.UserServicelmpl/>的编写;然后使用@Resource注解标注在属性userDao上,这相当于配置文件中<propertyname=“userDao” ref=“userDao”/> 的写法;最后在该类的save()方法中调用userDao中的save()方法,并输出一句话。

UserController.java

package com.wz.assemble.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;

@Controller("userController")
/*
 * @Controller用 于将控制层(如Spring MVC中的Controller )的类标识为Spring中的Bean
然后使用@Resource
注解标注在属性userService. 上,
相当于配置文件中<property name="userService" ref-"userService"/>的写法
 */
public class UserController {
		@Resource(name="userService")
		private UserService userService;

		public void setUserService(UserService userService) {
			this.userService = userService;
		}
		public void save()
		{
			this.userService.save();
			System.out.println("Controller层....save...");
		}
		
	
}

首先使用@Controller注解标注了UserController 类,这相当于在配置文件中编写<bean id=‘userCortroller’ class='com.itheima annotation.UserController/>;然后使用了@Resource注解标注在userService 属性上,这相当于在配置文件中编写<propertyname=“userService” ref=“userService” /> ;最后在其save()方法中调用了userService中的save()方法,并输出一句话。

beans6.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
      http://www.springframework.org/schema/context 
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">
  
<!--使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析-->   
    <context:component-scan base-package="com.wz.assemble.annotation" />
</beans>
    

AnnotationAssembleTest.Java

package com.wz.assemble.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationAssembleTest {
	public static void main(String[] args) {
		// 定义配置文件路径
		String xmlPath = "com/wz/assemble/annotation/beans6.xml";
		// 加载配置文件
		ApplicationContext applicationContext = 
				new ClassPathXmlApplicationContext(xmlPath);
		// 获取UserController实例
		UserController userController = 
		  (UserController) applicationContext.getBean("userController");
		// 调用UserController中的save()方法
		userController.save();
	}
}  

3.自动装配
虽然使用注解的方式装配Bean,在一定程度 上减少了配置文件中的代码量,但是也有企业项目中,是没有使用注解方式开发的,那么有没有什么办法既可以减少代码量,又能够实现Bean的装配呢?答案是肯定的,Spring 的元素中包含一个autowire 属性,我们可以通过设置autowire的属性值来自动装配Bean。所谓自动装配,就是将一个Bean自动地注入到其他Bean的Property中。
(1)修改文件UserServicelmpl和文件UserController, 分别在文件中增加类属性的setter方法。(在设值注入中有详解)
(2 )修改上述的配置文件beans6.xml,将配置文件修改成自动装配形式。

<?xml version="1.0" encoding= "UTF-8"?>
<beans xmlns="http://www . springframework . org/schema/beans
xmlns:xsi="http://www. w3. org/2001/XML Schema- instance'
xmIns : context="http:/ /ww. springframework . org/ schema/ context"
xsi : schemaLocation="http:/ /www. springframework . org/ schema/ beans
http:/ /ww. springframework . org/ schema/beans/ spring- beans -4.3. xsd
http:/ /ww. springframework . org/ schema/ context
http://ww. springframework . org/schema/ context/ spring - context -4.3.xsd">
<!--使用bean元素的autowire属性完成自动装配-->
<bean id= "userDao"class="com. itheima. annotation.UserDaoImpl" />
<bean id="userService"class="com. itheima. annotation. UserServiceImpl" autowire="byName" />
<bean id="userController"class="com. ithe ima. annotation . UserController" autowire= "byName" />
</beans>

用于配置userService和userController的元素中除了id和class属性外,还增加了autowire 属性,并将其属性值设置为byName。 在默认情况下,配置文件中需要通过ref来装配Bean,但设置autowire="byName"后,Spring 会自动寻找userServiceBean中的属性,并将其属性名称与配置文件中定义的Bean做匹配。由于UserServicelmpl中定义了userDao属性及其setter方法,这与配置文件中id为userDao的Bean相匹配,所以Spring会自动地将id为userDao的Bean装配到id为userService的Bean中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值