我们已经了解了Spring的基本应用以及Bean的实例化的三种方式,接下来学习Bean的装配方式。
Bean的装配我们可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Bean的装配方式有三种:基于XML的装配、基于注解(Annotation)的装配和自动装配。接下来我对三种装配方式进行详细的解释以及实现。
1.基于XML的装配
Spring提供了两种基于XML的装配方式:设值注入(Setter Injection)和构造注入(Constructor Injection)。
设值注入须满足的条件:
Bean类必须有一个默认的无参构造方法
Bean类必须为属性提供setter方法
在配置文件中,使用<property>元素为每个属性注入值
构造注入须满足的条件:
Bean类必须提供有参构造方法
在配置文件中,使用<constructor-arg>元素来为参数注入值
(1).打开Eclipse,在SpringTest项目的src目录下,创建一个com.example.xml包,包中创建User类。
package com.example.xml;
import java.util.List;
public class User {
private String name;
private int age;
private List<String> list;
//构造注入
public User(String name, int age, List<String> list) {
super();
this.name = name;
this.age = age;
this.list = list;
}
//设值注入
public User() {
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", list=" + list + "]";
}
}
(2).在com.example.xml包中,创建Spring的配置文件beans.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.xsd">
<!-- 构造注入 -->
<bean id="user1" class="com.example.xml.User">
<constructor-arg index="0" value="zhangsan"></constructor-arg>
<constructor-arg index="1" value="20"></constructor-arg>
<constructor-arg index="2">
<list>
<value>构造注入1</value>
<value>构造注入2</value>
</list>
</constructor-arg>
</bean>
<!-- 设值注入 -->
<bean id="user2" class="com.example.xml.User">
<property name="name" value="lisi"></property>
<property name="age" value="24"></property>
<property name="list">
<list>
<value>设值注入1</value>
<value>设值注入2</value>
</list>
</property>
</bean>
</beans>
(4).在com.example.xml包中,创建测试类TestXml。
package com.example.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestXml {
public static void main(String[] args) {
String xmlPath = "com/example/xml/beans.xml";
ApplicationContext ac =
new ClassPathXmlApplicationContext(xmlPath);
User user1 = (User) ac.getBean("user1");
System.out.println(user1);
//System.out.println(ac.getBean("user1"));
User user2 = (User) ac.getBean("user2");
System.out.println(user2);
//System.out.println(ac.getBean("user2"));
}
}
运行结果:
2.基于Annotation的装配
基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation技术的全面支持。
常用的注释如下表:
注解 | 描述 |
---|---|
@Component | 描述Spring中的Bean,它是一个泛化的概念,仅仅表示一个组件。 |
@Repository | 用于将数据访问层(DAO)的类标识为Spring中的Bean 。其功能与@Component相同。 |
@Service | 用于将业务层(Service)的类标识为Spring中的Bean。其功能与@Component相同。 |
@Controllerd | 用于将控制层(Controller)的类标识为Spring中的Bean 。其功能与@Component相同。 |
@Autowired | 用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。 |
@Resource | 其作用与Autowired一样。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。 |
@Qualifier | 与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。 |
注:在实际开发中为了使标注类用途更加清晰,我们使用@Repository、@Service、@Controllerd对实现类进行标注。
@Component 取代 <bean class=" ">
@Component(“id”) 取代 <bean id=" " class=" ">
@Repository,@Service,@Controller取代<bean class=" ">
@Repository(“id”),@Service(“id”),@Controller(“id”)取代<bean id=“ ” class=" ">
(1).打开Eclipse,在SpringTest项目的src目录下,创建一个com.example.annotation包,包中创建UserDao接口。
package com.example.annotation;
public interface UserDao {
public void addUser();
}
(2).在com.example.annotation包,创建UserDaoImplement类。
package com.example.annotation;
import org.springframework.stereotype.Component;
@Component("userId")
public class UserDaoImplement implements UserDao{
@Override
public void addUser() {
System.out.println("add....user....");
}
}
(3).在com.example.annotation包中,创建Spring的配置文件beans.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example.annotation"></context:component-scan>
</beans>
(4).在com.example.annotation包中,创建测试类TestAnnotation。
package com.example.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAnnotation {
public static void main(String[] args) {
String xmlPath = "com/example/annotation/beans.xml";
ApplicationContext ac =
new ClassPathXmlApplicationContext(xmlPath);
UserDao userDao = (UserDao) ac.getBean("userId");
userDao.addUser();
}
}
运行结果:
接下来使用@Repository、@Service、@Controllerd来进行对基于Annotation的装配的进一步理解。
(1).打开Eclipse,在SpringTest项目的src目录下,创建一个com.example.annotationDaoServiceController包,包中创建UserDao,UserService,UserController接口。
package com.example.annotationDaoServiceController;
public interface UserDao {
public void use();
}
package com.example.annotationDaoServiceController;
public interface UserService {
public void use();
}
package com.example.annotationDaoServiceController;
public interface UserController {
public void use();
}
(2).在com.example.annotationDaoServiceController包,创建UserDaoImplement类,使用@Repository注解。
package com.example.annotationDaoServiceController;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImplement implements UserDao{
@Override
public void use() {
System.out.println("use @Repository");
}
}
创建UserServiceImplement类,使用@Service注解。使用@Resource注解,相当于在配置文件中<property name=“userDao” ref="userDao’’>
package com.example.annotationDaoServiceController;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImplement implements UserService{
@Resource(name="userDao")
private UserDao UserDao;
@Override
public void use() {
this.UserDao.use();
System.out.println("use @Service");
}
}
创建serControllerImplement类,使用@Controller注解。使用@Resource注解,相当于在配置文件中<property name=“userService” ref="userService’’>
package com.example.annotationDaoServiceController;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
@Controller("userController")
public class UserControllerImplement implements UserController{
@Resource(name="userService")
private UserService userService;
@Override
public void use() {
this.userService.use();
System.out.println("use @Controller");
}
}
(3).在com.example.annotationDaoServiceController包中,创建Spring的配置文件beans.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example.annotationDaoServiceController"></context:component-scan>
</beans>
(4).在com.example.annotationDaoServiceController包中,创建测试类Test。
package com.example.annotationDaoServiceController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
String xmlPath = "com/example/annotationDaoServiceController/beans.xml";
ApplicationContext ac =
new ClassPathXmlApplicationContext(xmlPath);
UserController userController = (UserController) ac.getBean("userController");
userController.use();
}
}
运行结果:
3.自动装配
自动装配:将一个Bean自动的注入到到其他Bean的Property中。 Spring的<bean>元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。autowire属性有5个值,其值及说明下表所示:
属性名 | 描述 |
---|---|
default(默认值) | 由<bean>的上级标签<beans>的default-autowire属性值确定。例如<beans default- autowire="byName">该<bean>元素中的autowire属性对应的属性值为byName。 |
byName | 根据属性的名称自动装配。容器将根据名称查找与属性完全一致的Bean,并将其属性自动装配。 |
byType | 根据属性的数据类型(Type) 自动装配,如果一个Bean的数据类型,兼容另一个Bean中属性的数据类型,则自动装配。 |
constructor | 根据构造函数参数的数据类型,进行byType模式的自动装配。 |
no | 默认情况下,不使用自动装配,Bean 依赖必须通过ref元素定义。 |
byName通过Bean的id或name装配,byType按Bean的Class的类型装配。
byName:比如说类Information有个属性information,指定autowire为byName后,Spring IoC容器会在配置文件中查找id / name属性为information的bean,使用Seter方法注入。
byType:比如类Person有个属性information,类型为Information,指定autowire为byType后,Spring IoC容器会查找Class属性为Information的bean,使用Seter方法注入。
(1).打开Eclipse,在SpringTest项目的src目录下,创建一个com.example.autowire包,包中创建Information类。
package com.example.autowire;
public class Information {
private String sex;
private int age;
String address;
public String getSex() {
return getSex();
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Information [sex=" + sex + ", age=" + age + ", address=" + address + "]";
}
}
(2).在com.example.autowire包,创建Person类。
package com.example.autowire;
public class Person {
private String name;
private Information information;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Information getInformation() {
return information;
}
public void setInformation(Information information) {
this.information = information;
}
@Override
public String toString() {
return "Person [name=" + name + ", information=" + information + "]";
}
}
(3).在com.example.autowire包中,创建Spring的配置文件beans.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="information" class="com.example.autowire.Information"
p:sex="男" p:age="18" p:address="济南" ></bean>
<bean id="person" class="com.example.autowire.Person" autowire="byName"
p:name="zhangsan"></bean>
</beans>
(4).在com.example.autowire包中,创建测试类TestAutowire。
package com.example.autowire;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAutowire {
public static void main(String[] args) {
String xmlPath = "com/example/autowire/beans.xml";
ApplicationContext ac =
new ClassPathXmlApplicationContext(xmlPath);
Person person = (Person) ac.getBean("person");
System.out.println(person);
}
}
运行结果:
这就是Bean的装配方式,若有错漏,欢迎指正,希望大家一起学习进步!!!!
如果转载以及CV操作,请务必注明出处,谢谢!