在spring中反射创建实例,会绕过spring自动管理
当通过反射创建实例时,手动注入依赖需要小心处理,因为会绕过 Spring 的自动管理。导致在实例中无法通过注解去获取对象。
1.假设我有一个接口,该接口有两个实现类
public interface VerifyWzx {
public List<String> verify(List<String> ids);
}
@Service
public class UserRefRoleImpl implements VerifyWzx {
@Resource
UserRefRoleRep userRefRoleRep;
@Override
public List<String> verify(List<String> ids) {
List<String> list = Lists.newArrayList();
if (CollectionUtils.isNotEmpty(ids)){
for (String id : ids) {
UserRefRole userRefRole = userRefRoleRep.findByUserId(id);
if (userRefRole == null){
list.add(id);
}
}
}
return list;
}
}
@Service
public class OtherImpl implements VerifyWzx {
// Other implementation details
}
3.创建类的工厂(错误演示)
@Service
public class VerifyImplClazz {
public VerifyWzx make(String type){
VerifyWzx verifyWzx = null;
try {
String className = "com.geostar.exampl.jpaencrypt.factory.ext."+type;
Class<?> clazz = Class.forName(className);
Constructor<?> constructor = clazz.getDeclaredConstructor();
verifyWzx = (VerifyWzx) constructor.newInstance();
}catch (Exception e){
System.out.println("反射创建对象异常");
e.printStackTrace();
}
return verifyWzx;
}
}
4.当我通过工厂创建对象,执行方法
VerifyWzx verifyWzx = factory.make(type);
List<String> verify = verifyWzx.verify(ids);
此时是在UserRefRoleImpl实现类中是无法通过 @Resource UserRefRoleRep userRefRoleRep; 获取对象,原因是因为绕开了Spring 的自动管理
5.如何修改,首先要有一个概念,获取不到对象的原因的是因为spring扫描不到它。两种思路解决:
1.思路一:通过spring的上下 文直接获取对象,在UserRefRoleImpl类中,每个都得通过applicationcontext去拿,有点耦合。类似于通过new获取对象。
2.思路二:直接想办法让spring扫描到UserRefRoleImpl,此时要改造一下工厂类,在通过反射创建对象时,手动注入依赖
@Service
public class VerifyImplClazz {
@Autowired
private ApplicationContext applicationContext;
public VerifyWzx make(String type){
VerifyWzx verifyWzx = null;
try {
String className = "com.geostar.exampl.jpaencrypt.factory.ext."+type;
Class<?> clazz = Class.forName(className);
Constructor<?> constructor = clazz.getDeclaredConstructor();
verifyWzx = (VerifyWzx) constructor.newInstance();
applicationContext.getAutowireCapableBeanFactory().autowireBean(verifyWzx);
}catch (Exception e){
System.out.println("反射创建对象异常");
e.printStackTrace();
}
return verifyWzx;
}