在Spring中有三种装配的方式
- 在xml中 显式配置
- 在java中显式配置
- 隐式的自动装配bean
Spring Bean实现自动装配
自动装配就是指 Spring 容器在不使用 <constructor-arg>
和<property>
标签的情况下,可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。
下面使用IDEA 演示 Spring Bean 的自动装配:
- 创建一个Maven项目,添加相应的jar包
- 在src下创建一个实体类包(pojo),在包内创建people,proxy类,在resource包下创建配置文件bean.xml,测试类(Test.java)放在测试文件夹下
people类代码如下:
import org.springframework.beans.factory.annotation.Autowired;
public class people {
private proxy proxy;
public proxy getProxy() {
return proxy;
}
public void setProxy(proxy proxy) {
this.proxy = proxy;
}
}
proxy类代码如下:
public class proxy {
public void buy(){
System.out.println("买了一套房子");
}
}
Test.java:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.people;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
people people = (people) context.getBean("people");
people.getProxy().buy();
}
}
配置文件bean.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-3.0.xsd">
<!-- byName会在容器上下文中查找,和自己对象set方法后面的值对应的bean id-->
<bean id="people" class="pojo.people" autowire="byName"/>
<bean id="proxy" class="pojo.proxy"/>
</beans>
运行结果:
从这里看出,我们并没有对people类中proxy属性进行依赖注入,正常情况下应由<property name="proxy" ref="proxy"/>
实现对proxy的依赖注入,而Autowired会在容器上下文中查找和自己对象set方法后面的值对应的bean id,实现自动装配
Spring使用注解装配Bean
前景:在 Spring 中,尽管可以使用 XML 配置文件实现 Bean 的装配工作,但如果应用中 Bean 的数量较多,会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。我们可以使用注解来配置依赖注入。
使用注解须知:
- 导入约束,和之前的bean.xml的约束相比有所改变
- 配置注解的支持
<context:annotation-config/>
<?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-3.0.xsd">
<context:annotation-config/>
</beans>
Spring 中常用的注解如下。
- @Component
可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。 - @Repository
用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 - @Service
通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 - @Controller
通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 - @Autowired
可以应用到 Bean 的属性变量、属性的 setter 方法、非 setter 方法及构造函数等,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。 - @Resource
作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。-
@Resource 中有两个重要属性:name和type
- Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。
- 如果指定 name 属性,则按实例名称进行装配;
- 如果指定 type 属性,则按 Bean 类型进行装配。
- 如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;
- 如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
-
- @Qualifier
与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
下面使用IDEA展示Spring的注解配置:
- 创建一个Maven项目,导入相关的依赖
- 建包和对应的Java类,本代码为演示代码,并未创建相应的接口,避免代码的臃肿
- 在resource资源文件夹下创建ApplicationContext.xml配置文件
UserDao代码如下:
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDao {
public void addUser(){
System.out.println("添加了一个用户数据");
}
}
UserService代码如下:
import dao.UserDao;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service("userService")
public class UserService {
@Resource(name="userDao")
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addMessage(){
userDao.addUser();
System.out.println("打印出添加用户数据的日志");
}
}
UserController代码如下:
import org.springframework.stereotype.Controller;
import service.UserService;
import javax.annotation.Resource;
@Controller("userController")
public class UserController {
@Resource(name="userService")
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void show(){
userService.addMessage();
System.out.println("成功添加该用户数据");
}
}
ApplicationContext.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-3.0.xsd">
<!-- 指定要扫描的包,这个包下的注解才会生效-->
<context:component-scan base-package="pojo" />
<context:component-scan base-package="dao"/>
<context:component-scan base-package="service"/>
<context:component-scan base-package="controller"/>
<context:annotation-config/>
</beans>
测试类代码:
import controller.UserController;
import pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserController uc = context.getBean("userController",UserController.class);
uc.show();
}
}
测试结果:
以上每个层的类都用其对应的注解装配Bean,注解后的name属性即对应xml文件中的bean id ,自动装配时按照bean的实例名称进行装配。
以上即为Spring注解的解析。