使用静态吸气剂时,实例失去自动布线属性
问题描述:
我的Java类中有自动布线属性的问题。我有一个工厂,它有一个MyClass对象的Map<Integer, MyClass>
。 MyClasses有一个projectId属性,这就是我希望从工厂获得它们的方式。但是,如果使用public static MyClassFactory getInstance()
和public MyClassInterface createMyClass
,MyClasses中的自动装配属性在以这种方式检索时为null,但在插入到映射中时不为null。使用静态吸气剂时,实例失去自动布线属性
我想知道为什么发生这种情况以及如何避免这种情况。
除此之外,MyClass的范围设置为原型,但我不确定这是否能按照预期工作。任何想法,如果这项工作或如何执行这种行为?
@Configurable(preConstruction = true)
public class MyClassFactory {
@Autowired
private BeanFactory beanFactory;
private static volatile MyClassFactory instance = null;
private final HashMap<Integer, MyClass> classMap;
private MyClassFactory() throws MyClassAlreadyRegisteredException {
this.classMap = new HashMap<Integer, MyClassInterface>();
this.registerMyClasses();
}
private void registerMyClasses() throws MyClassAlreadyRegisteredException {
registerMyClass(beanFactory.getBean(MyClass.class));
registerMyClass(beanFactory.getBean(MyClass2.class));
...
}
private void registerMyClass(MyClassInterface myClassInterface) throws MyClassAlreadyRegisteredException {
for (int projectId : myClassInterface.getProjectIds()) {
if (classMap.containsKey(projectId)) {
throw new MyClassAlreadyRegisteredException(classMap.get(projectId).getClass().getName());
}
classMap.put(projectId, myClassInterface);
}
}
public static MyClassFactory getInstance() throws MyClassAlreadyRegisteredException {
MyClassFactory result = instance;
if (result == null) {
synchronized (MyClassFactory.class) {
result = instance;
if (result == null) {
instance = result = new MyClassFactory();
}
}
}
return result;
}
public MyClassInterface createMyClass(int projectId) throws NoMyClassRegisteredException, InstantiationException,
IllegalAccessException {
if (classMap.containsKey(projectId)) {
return classMap.get(projectId).create();
}
throw new NoMyClassRegisteredException("for projectId: " + projectId);
}
}
(如果我没有把足够的信息在这里,请告诉我,我会增加更多。)
答
您在这里混合单春豆Singleton模式。你应该避免这一点。
编辑:
为什么你就不能使用它作为单春豆?:
@Configurable(preConstruction = true)
public class MyClassFactory {
@Autowired
private BeanFactory beanFactory;
private final HashMap<Integer, MyClass> classMap;
@PostConstruct
private void init() throws MyClassAlreadyRegisteredException {
this.classMap = new HashMap<Integer, MyClassInterface>();
this.registerMyClasses();
}
private void registerMyClasses() throws MyClassAlreadyRegisteredException {
registerMyClass(beanFactory.getBean(MyClass.class));
registerMyClass(beanFactory.getBean(MyClass2.class));
...
}
private void registerMyClass(MyClassInterface myClassInterface) throws MyClassAlreadyRegisteredException {
for (int projectId : myClassInterface.getProjectIds()) {
if (classMap.containsKey(projectId)) {
throw new MyClassAlreadyRegisteredException(classMap.get(projectId).getClass().getName());
}
classMap.put(projectId, myClassInterface);
}
}
public MyClassInterface createMyClass(int projectId) throws NoMyClassRegisteredException, InstantiationException,
IllegalAccessException {
if (classMap.containsKey(projectId)) {
return classMap.get(projectId).create();
}
throw new NoMyClassRegisteredException("for projectId: " + projectId);
}
}
而且比你可以自动装配这个bean到任何弹簧驱动类。 但是你的局部变量classMap仍然存在线程安全问题。你应该通过传递和摆脱中级课程来解决这个问题。如果你需要在singleton bean中缓存,你需要使它成为线程安全的。
你能告诉我如何正确使用工厂吗? – DrunkenPope 2014-09-22 10:44:34