自动assembly不在Class @Entity中工作

我有一个名为Menu的类,注释为@Entity ,我需要在名为GestoreMessaggi的类中使用一个方法

.... @Component @Entity @Table(name="menu") public class Menu implements Serializable{ @Autowired @Transient // because i dont' save this field on the DB private GestoreMessaggi gestoreMessaggi; ..... public void setCurrentLanguage(){ /* I got the error both if use gestoreMessaggi this way and if I use the autowired istance of GestoreMessaggi*/ GestoreMessaggi gestoreMessaggi = new GestoreMessaggi(); gestoreMessaggi.gest(); } ..... 

这是GestoreMessaggi类的相关代码

  @Component public class GestoreMessaggi { @Autowired private ReloadableResourceBundleMessageSource messageSource; public void gest(){ messageSource.doSomething() <--- here messageSource is null } } 

什么时候,我打电话给gestoreMessaggi.gest(); 从Menu类,我收到一个错误,因为messageSource为null。 gestoreMessaggi istance不为null,只为messageSource为null

重要提示 :只有当我从注释为@Entity的类中调用GestoreMessaggi时,才会在messageSource上获取null。

在ds-servlet.xml中,我告诉Spring扫描包含Menu和GestoreMessaggi类的pakages:

 //Menu package  //Gestore messaggi package  

谢谢

您可以采用以下两种方法:

  1. 尝试从@Entity类的方法中获取Spring管理的bean的实例
  2. 按照@Stijn Geukens的建议更改设计,使您的实体成为POJO,无需任何逻辑或dependency injection机制

如果你选择选项1,你必须显式访问Spring的上下文并检索你需要的bean实例:

 @Component public class Spring implements ApplicationContextAware { private static final String ERR_MSG = "Spring utility class not initialized"; private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } public static  T bean(Class clazz) { if (context == null) { throw new IllegalStateException(ERR_MSG); } return context.getBean(clazz); } public static  T bean(String name) { if (context == null) { throw new IllegalStateException(ERR_MSG); } return (T) context.getBean(name); } } 

您需要让Spring扫描此类才能使其正常工作。

然后,在@EntityClass ,执行以下操作:

 public void setCurrentLanguage(){ GestoreMessaggi gestoreMessaggi = Spring.bean(GestoreMessaggi.class); gestoreMessaggi.gest(); } 

这就是全部。 请注意,您不再需要将GestoreMessaggi自动assembly到@Entity 。 另请注意, Spring和大多数社区都不推荐这种方法 ,因为它将您的域类(您的@Entity类)与Spring类耦合。

如果你选择选项2,那么你需要做的就是让Spring像往常一样解决自动assembly,但是在你的实体之外 (例如在dao或服务中),如果你的实体需要你填写一些消息或其他什么,只需在其上调用一个setter。 (那取决于您的要求,由您决定@Entity的属性@Transient与否)。

Spring上下文不管理实体(通常不管理使用new实例化的对象),这就是为什么你不能在实体中自动assemblybean(来自Spring的上下文)。

最佳实践建议在实体中仅保留getter和setter,将业务逻辑留给服务层。

一种常见的方法是Service <-> DAO <-> Entity 。 例:

服务层:

 @Service public interface GestoreMessaggi { public void gest(); } public class GestoreMessaggiImpl implements GestoreMessaggi { @Autowired private MenuDao menuDao; @Override public void gest() { // 1) retrieve your entity instance with menuDao // 2) do stuffs with your entity // 3) maybe save your entity using menuDao } } 

DAO层:

如果您使用Spring Data Jpa:

 public interface MenuDao extends JpaRepository {} 

其他:

 public interface MenuDao { public Menu findOne([menu-id-type] id); public Menu save(Menu menu); // other methods for accessing your data } @Repository public class MenuDaoImpl { // inject EntityManager or Hibernate SessionFactory // implement your DAO interface accessing your entities } 

最后记得配置Spring的bean,包括配置中的@Service@Repository (显式或通过包扫描)。

使用Spring MVC,您应该在@Controller类中注入(autowire) @Service ,因此控制器可以调用调用DAO方法的服务方法,这些方法访问您的数据。