每次需要代理获取实例时,我都需要基于会话信息提供bean。我该怎么做?
现在我尝试了以下方法。例如:
第一个类定义了一个会话范围的bean。
ansible --version
ansible 2.7.5
config file = None
configured module search path = [u'/Users/lobo/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.11 (default, Jan 22 2016, 08:29:18) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)]
第二类具有与其领域相关的一些逻辑,并且知道如何提供信息。每次都要创建一个bean,因为信息可能在线程处理过程中发生变化。因此,每次使用@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BeanSession implements Serializable {
private Serializable rootState;
public <T extends Serializable> T getRootState() {
return (T) rootState;
}
public void setRootState(Serializable rootState) {
this.rootState = rootState;
}
}
时,我都将确保为bean提供新鲜的信息。
Attribute1
最后,第三类将@Service
public class Attribute1Service {
@Resource
private BeanSession beanSession;
public void setDefaultValue() {
Configuration configuration = beanSession.getRootState();
configuration.getAttribute1().setValue("VALUE 1");
}
@Bean
public Attribute1 attribute1() {
Configuration configuration = beanSession.getRootState();
return configuration.getAttribute1();
}
}
声明为执行自己的逻辑的依赖项。
attribute1
但是,问题是在创建@Service
public class Attribute2Service {
@Resource
private BeanSession beanSession;
@Resource
private Processor processor;
@Resource
private Attribute1 attribute1;
public void defineAttribute2() {
Configuration configuration = beanSession.getRootState();
String value = processor.getValue(configuration, attribute1);
configuration.getAttribute2().setValue(value);
}
public void defineAttribute3() {
Configuration configuration = beanSession.getRootState();
String value = processor.getValue(configuration, attribute1);
configuration.getAttribute3().setValue(value);
}
}
时出现以下错误:
attribute1
我不想访问org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Attribute2Service': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'attribute1' defined in class path resource [Attribute1Service.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [String]: Factory method 'attribute1' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.beanSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1378) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
...
上attribute1
的{{1}}信息,因为它会在信息提供者和使用者之间形成硬耦合。
答案 0 :(得分:1)
异常说明了一切-您的attribute1 bean是在应用程序初始化期间创建的(通过会话作用域bean),但是没有与请求绑定的线程。您还应该代理您的attribute1 bean,因为您要将其注入到singleton(属性2服务。)
答案 1 :(得分:0)
基于Alexander.Furer提供的见解。我创建了自己的作用域,并对其进行了管理,以调用Bean提供程序,使其在function myTestFunction () {
}
var myTestVar;
方法的每次访问中都具有新鲜的Bean。
为此,我扩展了以下范围:
Attribute1
新的// Register scope as "runtime"
public class RuntimeScope implements Scope {
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
return objectFactory.getObject();
}
...
}
服务:
Attribute1
消费者@Service
public class Attribute1Service {
@Resource
private BeanSession beanSession;
public void setDefaultValue() {
Configuration configuration = beanSession.getRootState();
configuration.getAttribute1().setValue("VALUE 1");
}
@Bean
@Scope(value = "runtime", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Attribute1 attribute1() {
Configuration configuration = beanSession.getRootState();
return configuration.getAttribute1();
}
}
服务:
Attribute2
我没有看到的问题是Attribute1应该是处理bean实例化的代理。因此,在创建自己的作用域时,我可以保证对attribute1(由@Service
public class Attribute2Service {
@Resource
private BeanSession beanSession;
@Resource
private Processor processor;
@Resource
private Attribute1 attribute1;
public void defineAttribute2() {
Configuration configuration = beanSession.getRootState();
String value = processor.getValue(configuration, attribute1.getValue()); // Will call Attribute1 service to require the fresh bean
configuration.getAttribute2().setValue(value);
}
public void defineAttribute3() {
Configuration configuration = beanSession.getRootState();
String value = processor.getValue(configuration, attribute1.getValue()); // Will call Attribute1 service to require the fresh bean
configuration.getAttribute3().setValue(value);
}
}
和Attribute2Service
制造)方法的访问将创建一个新鲜的bean(由attribute1.getValue()
提供)。