为什么Spring的@Configurable有时工作,有时不? [英] Why does Spring's @Configurable sometimes work and sometimes not?

查看:1015
本文介绍了为什么Spring的@Configurable有时工作,有时不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过Spring的@Configurable注解使用自动依赖注入W于该领域需要注入/ @Resource。这涉及到一些设置,比如通过弹簧agent.jar中我的JVM。对于所有细节看到这里

它的工作原理...居多。当我的Tomcat启动时,我看见AspectJ的初始化信息,我的用户将自动获得对象引用的FileService等。

问题是,有时它只是不会发生。这似乎是完全随机的;有时我开机和依赖关系没有注入,有时他们是。我previously曾与@Transactional是我的用户麻烦,因为它创造了一个矛盾,我相信,随着代理。我使用JPA,所以我的用户都标有@Entity,所以我最好的猜测现在的问题是,这是产生冲突。我读过你不能自动代理的代理。为了抵消冲突,我跟一些笔记我在网上找到有关排除 CGLIB Javassist是其中休眠(JPA我implement执行)使用。

线索:


  • 这是全有或全无。我所有的@Configurable实例已经注入或没有。

  • 重装(重新实例)从数据库实体不会出现帮助;它或者工作或没有。

  • 重新引导Tomcat的任何数量的时候也根本不会解决它。这似乎再一次掷骰子的唯一一件事就是重新部署。换句话说,如果我重新部署它可能工作。

我怎样才能弄清是怎么回事?是使用@Configurable使用JPA的人?为什么不是我的 dependencyCheck = TRUE 的抛出一个错误,当依赖性没有实际注入?

实体

  @Entity
@Configurable(dependencyCheck =真)
@NamedQueries({@NamedQuery(NAME =User.findAll,查询=选择用户与用户的用户),
@NamedQuery(NAME =User.findByEmail,查询=选择用户与用户的用户WHERE user.email =:电子邮件)})
公共抽象类用户扩展BaseModel {私有静态最后的serialVersionUID长= 7881431079061750040L;@ID
@GeneratedValue(策略= GenerationType.TABLE)
私人长期身份证;@Column(唯一= TRUE,可为空= FALSE)
私人字符串电子邮件;@Basic(可选= FALSE)
私人字符串密码;@Resource
私人短暂UserEmailer userEmailer;@Resource
私人短暂的FileService的FileService;...

aop.xml文件

 <!DOCTYPE AspectJ的PUBLIC
     - // AspectJ的// DTD // ENhttp://www.eclipse.org/aspectj/dtd/aspectj.dtd\">
<&AspectJ的GT;
    <韦弗选项= - 冗长>
<包括=com.myapp.domain .. */&GT之内;
<排除=*。* CGLIB */&GT之内;
<排除=*。* * Javassist是/&GT之内;
    < /韦弗>
    <&方面GT;
<外观名称=org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect/>
    < /&方面GT;
< / AspectJ的>

的applicationContext.xml

  ...<背景:弹簧配置/><背景:加载时,韦弗/><背景:组件扫描基包=com.myapp/>...


解决方案

要我这听起来像一个众所周知的bug在春天的occurence:的 http://jira.springframework.org/browse/SPR-5401

能不能您尝试在多个应用程序上下文中使用可配置?在这种情况下,其中只有一个会受到依赖注入。哪一个获胜取决于哪个应用程序上下文要加载的最后一个。

解决方案?无:-(没有计划来解决这个问题。那就是至少是SpringSource的家伙说在四月在德国JAX会议。

I'm trying to use automatic dependency injection via Spring's @Configurable annotation w/ @Resource on the fields needing injection. This involved some setup, like passing spring-agent.jar to my JVM. For the full details see here.

It works... mostly. When my Tomcat is booting up, I see the AspectJ init messages, my User objects automatically get FileService references, etc.

The problem is that sometimes it just doesn't happen. It appears to be completely random; sometimes I boot up and the dependencies are not injected, sometimes they are. I previously had trouble with @Transactional being on my User because it created a conflict, I believe with proxies. I am using JPA, so my User is marked with @Entity, so my best guess right now is that this is creating a conflict. I've read you can't auto proxy a proxy. To offset the conflict, I followed some notes I found online about excluding CGLIB and javassist which Hibernate (my JPA impl) uses.

Clues:

  • It's all or nothing. All of my @Configurable instances have been injected or none of them.
  • Reloading (reinstantiating) the Entity from the DB doesn't appear to help; it's either working or not.
  • Rebooting Tomcat any number of time also won't even fix it. The only thing that appears to roll the dice again is a redeploy. In other words, if I redeploy it may work.

How can I figure out what is going wrong? Is anyone using @Configurable with JPA? Why isn't my dependencyCheck = true throwing an error when dependencies are not actually injected?

Entity

@Entity
@Configurable(dependencyCheck = true)
@NamedQueries( { @NamedQuery(name = "User.findAll", query = "SELECT user FROM User user"),
	@NamedQuery(name = "User.findByEmail", query = "SELECT user FROM User user WHERE user.email = :email") })
public abstract class User extends BaseModel {

private static final long serialVersionUID = 7881431079061750040L;

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;

@Column(unique = true, nullable = false)
private String email;

@Basic(optional = false)
private String password;

@Resource
private transient UserEmailer userEmailer;

@Resource
private transient FileService fileService;

...

aop.xml

<!DOCTYPE aspectj PUBLIC
    "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver options="-verbose">
	    <include within="com.myapp.domain..*" />
	    <exclude within="*..*CGLIB*" />
	    <exclude within="*..*javassist*" />
    </weaver>
    <aspects>
	    <aspect name="org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect" />
    </aspects>
</aspectj>

applicationContext.xml

...

<context:spring-configured />

<context:load-time-weaver />

<context:component-scan base-package="com.myapp" />

...

解决方案

To me it sounds like an occurence of a well known bug in Spring: http://jira.springframework.org/browse/SPR-5401.

Can it be that you are trying to use Configurable in several application contexts? In this case only one of them will be subject to dependency injection. Which one wins depends on which application context is the last one to be loaded.

Solution? None :-( There are no plans to fix this issue. That is at least what the SpringSource guy told at the JAX conference in Germany in April.

这篇关于为什么Spring的@Configurable有时工作,有时不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆