Spring Singleton和@Autowired返回NULL
我有一个存储库管理器来管理我的存储库。我有@Autowired来实例化我的属性,但它们总是空的。在我的xml中正确配置了bean。有什么原因吗Spring Singleton和@Autowired返回NULL,spring,singleton,autowired,Spring,Singleton,Autowired,我有一个存储库管理器来管理我的存储库。我有@Autowired来实例化我的属性,但它们总是空的。在我的xml中正确配置了bean。有什么原因吗 public class RepositoryManager { private static RepositoryManager instance; private RepositoryManager() { } public static RepositoryMana
public class RepositoryManager {
private static RepositoryManager instance;
private RepositoryManager()
{
}
public static RepositoryManager Instance()
{
if(instance == null)
instance = new RepositoryManager();
return instance;
}
@Autowired
private IUserRepository userRepository;
@Autowired
private IRoleRepository roleRepository;
@Autowired
private IAssetRepository assetRepository;
public IUserRepository getUserRepository() {
return userRepository;
}
public void setUserRepository(IUserRepository userRepository) {
this.userRepository = userRepository;
}
public IRoleRepository getRoleReposttory() {
return roleRepository;
}
public void setRoleReposttory(IRoleRepository roleRepository) {
this.roleRepository = roleRepository;
}
public IAssetRepository getAssetRepository() {
return assetRepository;
}
public void setAssetRepository(IAssetRepository assetRepository) {
this.assetRepository = assetRepository;
}
}
dao.xml
<!-- Scans within the base package of the application for @Components to configure as beans -->
<context:component-scan base-package="com.cisco.badges.data.*" />
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="annotatedClasses">
<list>
<value>com.cisco.badges.data.domain.User</value>
<value>com.cisco.badges.data.domain.Role</value>
<value>com.cisco.badges.data.domain.Asset</value>
<value>com.cisco.badges.data.domain.UserRole</value>
<value>com.cisco.badges.data.domain.UserRole$UserRolePK</value>
<value>com.cisco.badges.data.domain.UserAsset</value>
<value>com.cisco.badges.data.domain.UserAsset$UserAssetPK</value>
</list>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
com.cisco.badges.data.domain.User
com.cisco.badges.data.domain.Role
com.cisco.badges.data.domain.Asset
com.cisco.badges.data.domain.UserRole
com.cisco.badges.data.domain.UserRole$UserRolePK
com.cisco.badges.data.domain.UserAsset
com.cisco.badges.data.domain.UserAsset$UserAssetPK
类路径:hibernate.cfg.xml
真的
真的
userrepository.java
@Repository("userRepository")
public class UserRepository extends
BaseRepository<User, Long> implements
IUserRepository {
@Autowired
public UserRepository(SessionFactory sessionFactory) {
super(sessionFactory);
}
@Repository(“userRepository”)
公共类UserRepository扩展
BaseRepository实现
IUSER存储库{
@自动连线
公共用户存储库(SessionFactory SessionFactory){
超级(sessionFactory);
}
请确保配置中包含以下内容:
<context:annotation-config />
<context:component-scan base-package="name.of.your.package"></context:component-scan>
如果您有它,那么发布您的配置xml我自己也遇到了这个问题。问题是当您这样做时
new RepositoryManager();
在Instance()中,您没有使用Spring创建RepositoryManager,因此您的实例没有发生依赖项注入(没有自动连接)
解决方案是取消Instance()单例模式
@Component
@Scope(value = "singleton")
public class RepositoryManager {
...
}
然后,无论您在哪里需要存储库管理器,只需自动连接对它的引用(假设调用bean也由Spring管理!)
发生这种情况的原因是静态方法
Instance()
您正在spring上下文之外创建POJO
您可以通过将
添加到您的配置中,然后用@Configurable
注释RepositoryManager
来解决这个问题,实际上有一种非常优雅的方式可以吃蛋糕,也就是说,有一个同样由Spring管理的JVM单体。假设您有一个纯java单体,它有一个自动连接的bean,如下所示:
public final class MySingletonClass{
private static MySingletonClass instance;
public static MySingletonClass getInstance(){
if(instance==null){
synchronized{
if(instance==null){
instance = new MySingletonClass();
}
}
}
return instance;
}
@Autowired
private SomeSpringBean bean;
// other singleton methods omitted
}
只需在应用程序上下文中添加以下行,即可强制Spring管理此单例:
<bean class="com.mypackage.MySingletonClass" factory-method="getInstance"/>
现在,您的单例将有一个SomeSpringBean
autowired的实例(如果上下文中可用)
此外,这是对Spring singleton bean的典型问题的“修复”,这些bean不是真正的JVM singleton,因为它们是由Spring实例化的。使用上面的模式将强制执行JVM级别的singleton,即编译器强制的singleton,以及容器的singleton。如果bean配置正确,您的字段将不会被删除我添加了xml和示例存储库。同一存储库可以作为控制器中的属性手动注入,但在这个静态方法中,它没有被填充。(a)为什么
RepositoryManager
管理它自己的单例?(b)Spring中的RepositoryManager在哪里定义?它在哪个包中?(c)当您已经声明了组件扫描时,为什么还要声明显式存储库bean?a.)修复了单例语法b.)我在RepositoryManager上添加了@component,它位于包com.cisco.badges.data.repositories中;c.)我从xml中删除了它们,并且只使用注释相同的事情发生了我有注释驱动组件扫描我想你也需要,请看这个例子,我也看了我的代码,我在那里看到了。同样的事情。我认为这与它的单例部分有关?也许,你能回答@skaffman的问题吗?无论如何,这是一个非常有趣的问题。
<bean class="com.mypackage.MySingletonClass" factory-method="getInstance"/>