上一篇博客《spring依赖注入(dependency injection)》介绍了依赖注入的几种方式,今天来看下自动装配--autowire。
创建java项目,结构如下
UserDao代码
public interface UserDao {
public void getUser();
}
UserDaoImpl代码
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
UserDaoOracleImpl代码
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Oracle获取用户数据");
}
}
UserService代码
public interface UserService {
public void getUser();
}
UserServiceImpl代码
public class UserServiceImpl implements UserService{
private UserDao userDao=null;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
1、byName装配
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="userDao" class="com.test.dao.impl.UserDaoImpl"/>
<!-- autowire:自动装配 简化spring配置
byName:根据bean对应的class中的属性对应的set方法名称在beans.xml中找到相应的bean,
如果有则装配上;如果没有则不装配。
-->
<bean id="service" class="com.test.service.impl.UserServiceImpl"
autowire="byName">
</bean>
</beans>
service对应的bean中的类中属性有一个setUserDao()方法,这个setUserDao()方法去掉set后剩下的首字母小写是UserDao,然后在beans.xml配置中寻找id为UserDao的bean,如果找到了,就对应装配成这个bean的class,如果找不到,就不装配。
测试类Test代码
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
UserService us=(UserService) ac.getBean("service");
us.getUser();
}
}
执行结果如下
获取用户数据
为了解决在beans.xml中的每一个bean后面都装配autowire,所以还有一种简便的写法,就是在头文件处写default-autowire="byName",如图:
2、byType装配
byType(建议慎用):根据类型进行自动装配,不用管bean的id,但是同一种类型的bean只能有一个。
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="userDaoImpl" class="com.test.dao.impl.UserDaoImpl"/>
<bean id="oracleDaoImpl" class="com.test.dao.impl.UserDaoOracleImpl"/>
<bean id="service" class="com.test.service.impl.UserServiceImpl"
autowire="byType">
</bean>
</beans>
运行测试结果报错,因为配置文件中有两个UserDao的实现类,容器不知道找那个,所以这种情况很容易出现错误,建议慎用!
如果想运行正常,只能存在一个UserDao的实现类。
3、constructor装配
constructor:当通过构造器注入实例化bean时适用byType的方式装配构造方法。
将UserServiceImpl代码中的set方法去掉,增加构造方法,如下:
public class UserServiceImpl implements UserService{
private UserDao userDao=null;
public UserServiceImpl(UserDao userDao) {
super();
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
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="userDaoImpl" class="com.test.dao.impl.UserDaoImpl"/>
<bean id="service" class="com.test.service.impl.UserServiceImpl"
autowire="constructor">
</bean>
</beans>
bean的作用域
scope指bean的作用域,在配置bean时,有scope属性来配置bean的作用域
<!-- bean的作用域
singleton单例 整个容器只有一个对象实例 默认是单例
prototype原型 每次获取bean都产生一个新的对象
request 每次请求时创建一个新的对象
session 在会话的范围内时一个对象
global session 只在Portlet下有用,表示是application
application 在应用范围中一个对象
-->
<bean id="addr" class="com.test.vo.Address">
<property name="address" value="回龙观"/>
</bean>
注意:在整合struts2和spring时需要将action设为scop="prototype"