【Spring5.x】解决在注入时scope属性失效
<bean id="userDAO" class="com.zhl.UserDAOImpl" scope="prototype"/>
<bean id="userService" class="com.zhl.UserServiceImpl">
<property name="userDAO" ref="userDAO"/>
</bean>
package com.zhl;
/**
* <p>使用注入的方式获取 userDAO
*
* @author zhl
* @since 2024-05-11 18:23
*/
public class UserServiceImpl implements UserService{
private UserDAO userDAO;
@Override
public void register() {
userDAO.save();
System.out.println("userDAO = " + userDAO);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
public class SpringTest{
/**
* 测试 scope 属性失效
* 根据<bean id="userDAO" 获取 userDAO 对象
*/
@Test
public void scopeInvalidTest1() {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserDAO userDAO = (UserDAO) beanFactory.getBean("userDAO");
UserDAO userDAO1 = (UserDAO) beanFactory.getBean("userDAO");
userDAO.save();
userDAO1.save();
System.out.println(userDAO); //com.zhl.UserDAOImpl@3dd4520b
System.out.println(userDAO1); //com.zhl.UserDAOImpl@5ae63ade
}
/**
* 测试 scope 属性失效
* 根据 <bean id="userService" 获取 userService 对象
*/
@Test
public void scopeInvalidTest2() {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserService userService = (UserService) beanFactory.getBean("userService");
UserService userService1 = (UserService) beanFactory.getBean("userService");
// 在 UserService实现类register方法中调用并打印 userDAO
userService.register();
userService1.register();
}
}
在Spring的配置工厂中设置 userDAO 为prototype
非单例,每getBean()
一次就创建一个新的userDAO对象。
- 测试1:
- 测试2:
在UserServiceImpl中进行业务操作时,userDAO 必须保证线程安全,可以上锁,每次只能获取一个 userDAO 对象,但是这样效率太低,可以给每个线程分配一个userDAO。
在测试二有两个线程,userDAO对象始终为一个,说明在注入时,scope属性会失效。
解决方法
不使用注入,service类实现 BeanFactoryAware
接口
<bean id="userDAO" class="com.zhl.UserDAOImpl" scope="prototype"/>
<bean id="userService" class="com.zhl.UserServiceImpl"/>
package com.zhl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* <p>实现 BeanFactoryAware 传入 BeanFactory,通过 getBean() 获取
*
* @author zhl
* @since 2024-05-11 18:23
*/
public class UserServiceImpl implements UserService, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void register() {
UserDAO userDAO = (UserDAO) beanFactory.getBean("userDAO");
userDAO.save();
System.out.println("userDAO = " + userDAO);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
- 测试结果: