1.Spring基于XML装配Bean
Bean 的装配可以理解为依赖关系注入,Bean 的装配方式也就是 Bean 的依赖注入方式。Spring 容器支持多种形式的 Bean 的装配方式,如基于 XML 的 Bean 装配、基于 Annotation 的
Bean 装配和自动装配等。
Spring 基于 XML 的装配通常采用两种实现方式,即设值注入(Setter Injection)和构造注入(Constructor Injection)。本节将讲解如何在XML配置文件中使用这两种注入方式。
在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过 Java 的反射机制调用 setXxx() 方法进行属性的注入。因此,设值注入要求一个 Bean 的对应类必
须满足以下两点要求:
A.必须提供一个默认的无参构造方法。
B.必须为需要注入的属性提供对应的 setter 方法。
使用设值注入时,在 Spring 配置文件中,需要使用 <bean> 元素的子元素 <property> 元素为每个属性注入值。而使用构造注入时,在配置文件中,主要使用 <constructor-arg> 标签定义构造
方法的参数,可以使用其 value 属性(或子元素)设置该参数的值。
下面通过案例演示基于XML方式的Bean对不同类型数据的装配:
1.创建项目,完善结构,导入依赖
2.创建ClassBean类
package com.wangxing.springdemo6;
public class ClassBean {
private String classcode;
private String classname;
public String getClasscode() {
return classcode;
}
public void setClasscode(String classcode) {
this.classcode = classcode;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
}
3.创建StudentBean类
package com.wangxing.springdemo6;
import java.util.*;
public class StudentBean {
//基本类型数据
private int intvalue;
private double doublevalue;
private char charvalue;
private boolean booleanvalue;
//String
private String stringvalue;
//时间日期
private Date datevalue;
//对象型
private ClassBean classBean;
//数组
private String stringArrayvalue[];
private ClassBean classArrayvalue[];
//List
private List<String> stringListvalue;
private List<ClassBean> classListvalue;
//Set
private Set<String> stringSetvalue;
private Set<ClassBean> classSetvalue;
//Map
private Map<String,String> stringMapvalue;
private Map<String,ClassBean> classMapvalue;
//Properties
private Properties propertiesvalue;
public int getIntvalue() {
return intvalue;
}
public void setIntvalue(int intvalue) {
this.intvalue = intvalue;
}
public double getDoublevalue() {
return doublevalue;
}
public void setDoublevalue(double doublevalue) {
this.doublevalue = doublevalue;
}
public char getCharvalue() {
return charvalue;
}
public void setCharvalue(char charvalue) {
this.charvalue = charvalue;
}
public boolean isBooleanvalue() {
return booleanvalue;
}
public void setBooleanvalue(boolean booleanvalue) {
this.booleanvalue = booleanvalue;
}
public String getStringvalue() {
return stringvalue;
}
public void setStringvalue(String stringvalue) {
this.stringvalue = stringvalue;
}
public Date getDatevalue() {
return datevalue;
}
public void setDatevalue(Date datevalue) {
this.datevalue = datevalue;
}
public ClassBean getClassBean() {
return classBean;
}
public void setClassBean(ClassBean classBean) {
this.classBean = classBean;
}
public String[] getStringArrayvalue() {
return stringArrayvalue;
}
public void setStringArrayvalue(String[] stringArrayvalue) {
this.stringArrayvalue = stringArrayvalue;
}
public ClassBean[] getClassArrayvalue() {
return classArrayvalue;
}
public void setClassArrayvalue(ClassBean[] classArrayvalue) {
this.classArrayvalue = classArrayvalue;
}
public List<String> getStringListvalue() {
return stringListvalue;
}
public void setStringListvalue(List<String> stringListvalue) {
this.stringListvalue = stringListvalue;
}
public List<ClassBean> getClassListvalue() {
return classListvalue;
}
public void setClassListvalue(List<ClassBean> classListvalue) {
this.classListvalue = classListvalue;
}
public Set<String> getStringSetvalue() {
return stringSetvalue;
}
public void setStringSetvalue(Set<String> stringSetvalue) {
this.stringSetvalue = stringSetvalue;
}
public Set<ClassBean> getClassSetvalue() {
return classSetvalue;
}
public void setClassSetvalue(Set<ClassBean> classSetvalue) {
this.classSetvalue = classSetvalue;
}
public Map<String, String> getStringMapvalue() {
return stringMapvalue;
}
public void setStringMapvalue(Map<String, String> stringMapvalue) {
this.stringMapvalue = stringMapvalue;
}
public Map<String, ClassBean> getClassMapvalue() {
return classMapvalue;
}
public void setClassMapvalue(Map<String, ClassBean> classMapvalue) {
this.classMapvalue = classMapvalue;
}
public Properties getPropertiesvalue() {
return propertiesvalue;
}
public void setPropertiesvalue(Properties propertiesvalue) {
this.propertiesvalue = propertiesvalue;
}
}
4.创建配置文件
<?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.xsd">
<!-- 创建SimpleDateFormat对象 -->
<!-- SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd"); -->
<bean id="sdf" class="java.text.SimpleDateFormat">
<!-- 构造方法注入 -->
<constructor-arg index="0" value="yyyy-MM-dd"></constructor-arg>
</bean>
<!-- 创建ClassBean -->
<bean id="class1" class="com.wangxing.springdemo6.ClassBean">
<property name="classcode" value="20201201"></property>
<property name="classname" value="java班"></property>
</bean>
<bean id="class2" class="com.wangxing.springdemo6.ClassBean">
<property name="classcode" value="20201101"></property>
<property name="classname" value="web前端"></property>
</bean>
<bean id="class3" class="com.wangxing.springdemo6.ClassBean">
<property name="classcode" value="20201010"></property>
<property name="classname" value="Android班"></property>
</bean>
<bean id="student" class="com.wangxing.springdemo6.StudentBean">
<!--基本类型数据-->
<property name="intvalue" value="1001"></property>
<property name="doublevalue" value="168.5"></property>
<property name="charvalue" value="A"></property>
<property name="booleanvalue" value="true"></property>
<!--String-->
<property name="stringvalue" value="zhangsan"></property>
<!--Date-->
<property name="datevalue">
<bean factory-bean="sdf" factory-method="parse">
<constructor-arg index="0" value="2021-04-10"></constructor-arg>
</bean>
</property>
<!--Object-->
<property name="classBean" ref="class1"></property>
<!--String Array-->
<property name="stringArrayvalue">
<array>
<value>zhangsan</value>
<value>lisisi</value>
<value>wangwu</value>
</array>
</property>
<!--Object Array-->
<property name="classArrayvalue">
<array>
<ref bean="class1"></ref>
<ref bean="class2"></ref>
<ref bean="class3"></ref>
</array>
</property>
<!--String List-->
<property name="stringListvalue">
<list>
<value>zhangsan</value>
<value>lisisi</value>
<value>wangwu</value>
</list>
</property>
<!--Object List-->
<property name="classListvalue">
<list>
<ref bean="class1"></ref>
<ref bean="class2"></ref>
<ref bean="class3"></ref>
</list>
</property>
<!--String Set-->
<property name="stringSetvalue">
<set>
<value>zhangsan</value>
<value>lisisi</value>
<value>wangwu</value>
</set>
</property>
<!--Object Set-->
<property name="classSetvalue">
<set>
<ref bean="class1"></ref>
<ref bean="class2"></ref>
<ref bean="class3"></ref>
</set>
</property>
<!--String Map-->
<property name="stringMapvalue">
<map>
<entry key="name1" value="zhangsan"></entry>
<entry key="name2" value="lisisi"></entry>
<entry key="name3" value="wangwu"></entry>
</map>
</property>
<!--Object Set-->
<property name="classMapvalue">
<map>
<entry key="test1" value-ref="class1"></entry>
<entry key="test2" value-ref="class2"></entry>
<entry key="test3" value-ref="class3"></entry>
</map>
</property>
<!-- Properties -->
<property name="propertiesvalue">
<props>
<prop key="mydriver" >com.jdbc.mydql.Driver</prop>
<prop key="myurl" >jdbc:mysql://127.0.0.1:3306/test</prop>
<prop key="myname" >root</prop>
<prop key="mypassword" >123456</prop>
</props>
</property>
</bean>
</beans>
5.测试
@Test
public void test1(){
ApplicationContext context=new ClassPathXmlApplicationContext("applictionContext.xml");
StudentBean studentBean=context.getBean("student",StudentBean.class);
System.out.println("intvalue=="+studentBean.getIntvalue());
System.out.println("doublevalue=="+studentBean.getDoublevalue());
System.out.println("charvalue=="+studentBean.getCharvalue());
System.out.println("booleanvalue=="+studentBean.isBooleanvalue());
System.out.println("stringvalue=="+studentBean.getStringvalue());
System.out.println("datevalue=="+studentBean.getDatevalue());
ClassBean classBean=studentBean.getClassBean();
System.out.println(classBean.getClasscode()+"=="+classBean.getClassname());
System.out.println("-------------------------------------");
System.out.println("String数组");
for(String str:studentBean.getStringArrayvalue()){
System.out.println("String数组--"+str);
}
System.out.println("-------------------------------------");
System.out.println("Object数组");
for(ClassBean classobj:studentBean.getClassArrayvalue()){
System.out.println("Object数组--"+classobj.getClasscode()+"=="+classobj.getClassname());
}
System.out.println("-------------------------------------");
System.out.println("String-List");
for(String strlist:studentBean.getStringListvalue()){
System.out.println("String-List--"+strlist);
}
System.out.println("-------------------------------------");
System.out.println("Object-List");
for(ClassBean classobjlist:studentBean.getClassListvalue()){
System.out.println("Object-List--"+classobjlist.getClasscode()+"=="+classobjlist.getClassname());
}
System.out.println("-------------------------------------");
System.out.println("String-Set");
for(String strset:studentBean.getStringSetvalue()){
System.out.println("String-Set--"+strset);
}
System.out.println("-------------------------------------");
System.out.println("Object-Set");
for(ClassBean classobjset:studentBean.getClassSetvalue()){
System.out.println("Object-Set--"+classobjset.getClasscode()+"=="+classobjset.getClassname());
}
System.out.println("-------------------------------------");
System.out.println("String-Map");
for(Map.Entry<String,String> entry:studentBean.getStringMapvalue().entrySet()){
System.out.println("String-Map--"+entry.getKey()+":"+entry.getValue());
}
System.out.println("-------------------------------------");
System.out.println("Object-Map");
for(Map.Entry<String,ClassBean> entry:studentBean.getClassMapvalue().entrySet()){
System.out.println("Object-Map--"+entry.getKey()+":"+entry.getValue().getClasscode()+"="+entry.getValue().getClassname());
}
System.out.println("-------------------------------------");
Properties properties=studentBean.getPropertiesvalue();
//properties.stringPropertyNames()得到所有的key值封装到Set集合
Iterator<String> propkeys=properties.stringPropertyNames().iterator();
while(propkeys.hasNext()){
String keyvalue=propkeys.next();
String myvalue=properties.getProperty(keyvalue);
System.out.println("Properties=="+keyvalue+"-"+myvalue);
}
}
2.Spring基于Annotation【注解】装配Bean
在 Spring 中,尽管使用 XML 配置文件可以实现 Bean 的装配工作,但如果应用中 Bean 的数量较多,会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。
Java 从 JDK 5.0 以后,提供了 Annotation(注解)功能,Spring 也提供了对 Annotation 技术的全面支持。Spring3 中定义了一系列的 Annotation(注解),常用的注解如下:
1)@Component
可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
@Component--默认使用@Component创建的Bean类的名称,首字母小写
@Component(name)--指定的名称
2)@Repository
用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Repository--默认使用@Repository创建的Bean类的名称,首字母小写
@Repository(name)--指定的名称
3)@Service
通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service--默认使用@Service创建的Bean类的名称,首字母小写
@Service(name)--指定的名称
4)@Controller
通常作用在控制层(如 Struts2 的 Action/SpringMVC的控制器类),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller--默认使用@Controller创建的Bean类的名称,首字母小写
@Controller(name)--指定的名称
5)@Autowired
用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。
6)@Resource
其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。
@Resource 中有两个重要属性:name 和 type。
Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。
如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
7)@Qualifier
与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
例如:
1.创建项目,完善结构,导入依赖
2.创建数据访问层实现类
package com.wangxing.springdemo7.dao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
/**
* 数据访问层的操作类
*/
//@Component("studentDao")
@Repository("studentDaoImpl")
public class StudentDaoImpl {
public void insertStudent(){
System.out.println("数据访问层添加方法");
}
}
3.创建业务访问层实现类
package com.wangxing.springdemo7.service;
import com.wangxing.springdemo7.dao.StudentDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 业务访问层操作类
*/
//@Component("studentService")
@Service("studentServiceImpl")
public class StudentServiceImpl {
//@Autowired
@Resource
private StudentDaoImpl studentDao;
public void apperndStudent(){
System.out.println("业务访问层添加方法");
studentDao.insertStudent();
}
}
4.创建控制层实现类
package com.wangxing.springdemo7.controller;
import com.wangxing.springdemo7.service.StudentServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
import javax.xml.ws.soap.Addressing;
/**
* 控制层操作类
*/
//@Component("studentController")
@Controller("studentController")
public class StudentController {
//@Autowired
@Resource
private StudentServiceImpl studentService;
public void addStudent(){
System.out.println("控制层添加方法");
studentService.apperndStudent();
}
}
5.创建Spring配置文件
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
<context:component-scan base-package="com.wangxing.springdemo7"></context:component-scan>
</beans>
6.测试
@Test
public void test1(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
StudentController studentController=context.getBean("studentController", StudentController.class);
studentController.addStudent();
}
3.Spring自动装配Bean
除了使用 XML 和 Annotation 的方式装配 Bean 以外,还有一种常用的装配方式——自动装配。自动装配就是指 Spring 容器可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将
一个 Bean 注入其他 Bean 的 Property 中。
要使用自动装配,就需要配置 <bean> 元素的 autowire 属性。autowire 属性有五个值,具体说明如表 1 所示。
表 1 autowire 的属性和作用 | |
名称 | 说明 |
byName | 根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的 Property 的 name 相同,则自动装配这个 Bean 到 Property 中。 |
byType | 根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配。 |
constructor | 根据构造方法的参数的数据类型,进行 byType 模式的自动装配。 |
autodetect | 如果发现默认的构造方法,则用 constructor 模式,否则用 byType 模式。 |
no | 默认情况下,不使用自动装配,Bean 依赖必须通过 ref 元素定义。 |
1.创建项目,完善结构,导入依赖
2.创建数据访问层实现类
package com.wangxing.springdemo8.dao;
/**
* 数据访问层实现类
*/
public class UserDaoImpl {
public void insertUser(){
System.out.println("数据访问层添加方法");
}
}
3.创建业务访问层实现类
package com.wangxing.springdemo8.service;
import com.wangxing.springdemo8.dao.UserDaoImpl;
/**
* 业务访问层实现类
*/
public class UserServiceImpl {
private UserDaoImpl userDaoImpl;
public UserDaoImpl getUserDaoImpl() {
return userDaoImpl;
}
public void setUserDaoImpl(UserDaoImpl userDaoImpl) {
this.userDaoImpl = userDaoImpl;
}
public void appendUser(){
System.out.println("业务访问层添加方法");
userDaoImpl.insertUser();
}
}
4.建控制层实现类
package com.wangxing.springdemo8.controller;
import com.wangxing.springdemo8.service.UserServiceImpl;
/**
* 控制层实现类
*/
public class UserController {
private UserServiceImpl userServiceImpl;
public UserServiceImpl getUserServiceImpl() {
return userServiceImpl;
}
public void setUserServiceImpl(UserServiceImpl userServiceImpl) {
this.userServiceImpl = userServiceImpl;
}
public void addUser(){
System.out.println("控制层添加方法");
userServiceImpl.appendUser();
}
}
5.创建Spring配置文件
<?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.xsd">
<bean id="userDao" class="com.wangxing.springdemo8.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.wangxing.springdemo8.service.UserServiceImpl" autowire="byType"></bean>
<bean id="userController" class="com.wangxing.springdemo8.controller.UserController" autowire="byType"></bean>
</beans>
6.测试
@Test
public void test1(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserController controller=context.getBean("userController", UserController.class);
controller.addUser();
}