Java 使用SpringAOP时JSF中的NotSerializableException
我目前在使用JSF2和Spring3AOP的组合时遇到了一个问题 该应用程序设计为经典的三层体系结构(Web、服务、数据库)。因此,Spring管理的JSFbean调用代表业务逻辑的服务bean 托管bean如下所示:Java 使用SpringAOP时JSF中的NotSerializableException,java,serialization,jsf-2,deserialization,spring-aop,Java,Serialization,Jsf 2,Deserialization,Spring Aop,我目前在使用JSF2和Spring3AOP的组合时遇到了一个问题 该应用程序设计为经典的三层体系结构(Web、服务、数据库)。因此,Spring管理的JSFbean调用代表业务逻辑的服务bean 托管bean如下所示: @Named("startPage") @Scope("view") public class ManagedBean implements Serializable { @Inject private ServiceBeanA serviceBeanA;
@Named("startPage")
@Scope("view")
public class ManagedBean implements Serializable {
@Inject
private ServiceBeanA serviceBeanA;
public void someMethod() {
serviceBean.doSomeBusinessLogic();
}
由于该Bean是视图范围的,所以它实现了可序列化,实例变量(在本例中为ServiceBeanA)也是可序列化的,如下所述:
到目前为止,一切正常
现在我想截取业务服务中声明的业务方法的调用。所以
我创建了一个进行一些基本日志记录的方面,并在spring配置中对其进行了降级:
<bean id="aspectLogging" class="my.package.AspectLogging" />
<aop:config>
<aop:aspect ref="aspectLogging">
<aop:pointcut id="serviceMethodInvocation" expression="execution(* my.services.ServiceBeanA.doSomeBusinessLogic())" />
<aop:around pointcut-ref="serviceMethodInvocation" method="performLogging" />
</aop:aspect>
</aop:config>
现在问题出现了:
SCHWERWIEGEND: Exiting serializeView - Could not serialize state: org.springframework.aop.aspectj.AspectJPointcutAdvisor
java.io.NotSerializableException: org.springframework.aop.aspectj.AspectJPointcutAdvisor
我在Springsource中发现了两个相同的问题描述(不幸的是没有得到解决)
当然,我不能简单地使用面向方面,但任何其他第三方库也可能出现同样的问题
我所做的是将持有业务服务的实例变量标记为transient
public class ManagedBean implements Serializable {
@Inject
private transient ServiceBeanA serviceBeanA;
public void someMethod() {
serviceBean.doSomeBusinessLogic();
}
在会话恢复(反序列化)之前,此操作可以正常工作。当然,变量(serviceBeanA)在反序列化后为空。我可以将Web容器(例如Tomcat)配置为不序列化会话,但此应用程序在云中运行,因此我不负责配置服务器
我唯一的想法就是通过提供
private synchronized void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
及
托管Bean中的方法
private synchronized void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
ApplicationContext context = new ClassPathXmlApplicationContext("services.spring-config.xml", "database.spring-config.xml");
this.ServiceBeanA = (ServiceBeanA) context.getBean("serviceBeanA");
}
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
这个解决方案是可行的,但它似乎是一个非常笨拙的、不合法的解决方案。我必须在每个使用服务Bean的托管Bean中重复几乎相同的代码。此外,托管bean以这种方式与Spring紧密耦合,因为它们导入Spring应用程序上下文以恢复服务变量
有人能想出更好的架构方法吗?提前谢谢 @meriton的可能复制品:非常感谢您的提示。这确实是一个复制品
private synchronized void writeObject(ObjectOutputStream s) throws IOException
private synchronized void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
ApplicationContext context = new ClassPathXmlApplicationContext("services.spring-config.xml", "database.spring-config.xml");
this.ServiceBeanA = (ServiceBeanA) context.getBean("serviceBeanA");
}
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}