Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring @EntityManager bean的Autowired vs@PersistenceContext_Spring_Jpa_Entitymanager - Fatal编程技术网

Spring @EntityManager bean的Autowired vs@PersistenceContext

Spring @EntityManager bean的Autowired vs@PersistenceContext,spring,jpa,entitymanager,Spring,Jpa,Entitymanager,以下两者之间的区别是什么: @Autowired private EntityManager em; 与: @PersistenceContext private EntityManager em; 这两个选项都适用于我的应用程序,但是我可以通过使用@Autowired注释来破坏某些东西吗?@PersistenceContext是为特定目的而设计的标准注释。而@Autowired用于Spring中的任何依赖项注入。使用@PersistenceContext可以更好地控制上下文,因为它可以指定

以下两者之间的区别是什么:

@Autowired
private EntityManager em;
与:

@PersistenceContext
private EntityManager em;

这两个选项都适用于我的应用程序,但是我可以通过使用
@Autowired
注释来破坏某些东西吗?

@PersistenceContext
是为特定目的而设计的标准注释。而
@Autowired
用于Spring中的任何依赖项注入。使用
@PersistenceContext
可以更好地控制上下文,因为它可以指定可选元素,例如名称、属性
@PersistenceContext
允许您指定要使用的持久性单元。您的项目可能有多个数据源连接到不同的数据库,
@PersistenceContext
允许您说出要在哪个数据库上操作

请查看此处的说明:
@PersistenceContext

不返回实体管理器实例


它返回容器管理的代理,该代理代表应用程序代码获取和释放存在上下文

您不应该使用
@Autowired
@PersistenceContext
为每个线程创建一个唯一的EntityManager。在生产应用程序中,可以有多个客户端同时调用应用程序。对于每个调用,应用程序都会创建一个线程。每个线程都应该使用自己的EntityManager。想象一下如果他们共享同一个EntityManager会发生什么:不同的用户将访问相同的实体

usually the EntityManager or Session are bound to the thread (implemented as a ThreadLocal variable).
资料来源:

资料来源:


请注意,
@PersistenceContext
注释来自
javax.persistence
包,而不是spring框架。在JavaEE中,JavaEE容器(又称应用服务器)使用它注入EntityManager。Spring借用了PersistenceContext注释来做同样的事情:为每个线程注入一个应用程序管理的(=非容器管理的)EntityManager bean,就像JavaEE容器那样

您可以创建以下
FactoryBean
以使
EntityManager
正确可注入,即使是通过构造函数注入:

/**
 * Makes the {@link EntityManager} injectable via <i>@Autowired</i>,
 * so it can be injected with constructor injection too.
 * (<i>@PersistenceContext</i> cannot be used for constructor injection.)
 */
public static class EntityManagerInjectionFactory extends AbstractFactoryBean<EntityManager> {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Class<?> getObjectType() {
        return EntityManager.class;
    }

    @Override
    protected EntityManager createInstance() {
        return entityManager;
    }

}
/**
*使{@link EntityManager}可通过@Autowired注入,
*所以它也可以被注入构造函数注入。
*(@PersistenceContext不能用于构造函数注入。)
*/
公共静态类EntityManagerInjectionFactory扩展了AbstractFactoryBean{
@持久上下文
私人实体管理者实体管理者;
@凌驾
公共类getObjectType(){
返回EntityManager.class;
}
@凌驾
受保护的EntityManager createInstance(){
返回实体管理器;
}
}

请注意,因为我们在内部使用了
@PersistenceContext
注释,所以返回的
EntityManager
将是一个合适的线程安全代理,因为它将通过字段注入(使用
@PersistenceContext
)直接在使用位置注入,但是应用程序中的影响是什么?考虑使用Spring的标准@事务。当使用@Autowired时,将出现与使用@PersistenceContext相同的行为,并且每个应用程序事务都有em?我认为使用
@PersistenceContext
通常是最佳实践,因为它更接近地描述了您试图实现的依赖注入类型。此外,它还专门为EntityManager的使用提供可选参数,当您有多个EntityManager时,这会很有用。从功能上讲,我相信您可以使用
@Autowired
实现相同的注入,但我建议使用设计为这样使用的注释。在谈论线程时,我可以确认这一点。例如,如果没有@PersistenceContext,我的应用程序将在其他线程中运行SQL insert/update,但不会对数据库进行任何更改。
/**
 * Makes the {@link EntityManager} injectable via <i>@Autowired</i>,
 * so it can be injected with constructor injection too.
 * (<i>@PersistenceContext</i> cannot be used for constructor injection.)
 */
public static class EntityManagerInjectionFactory extends AbstractFactoryBean<EntityManager> {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Class<?> getObjectType() {
        return EntityManager.class;
    }

    @Override
    protected EntityManager createInstance() {
        return entityManager;
    }

}