Singleton 和 @Autowired 返回 NULL
我有一个存储库管理器来管理我的存储库。我有 @Autowired 来实例化我的属性,但它们始终为空。 bean 在我的 xml 中配置正确。有什么理由吗?
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>
用户存储库.java
@Repository("userRepository")
public class UserRepository extends
BaseRepository<User, Long> implements
IUserRepository {
@Autowired
public UserRepository(SessionFactory sessionFactory) {
super(sessionFactory);
}
I have a repository manager that manages my repositories. I have the @Autowired to instantiate my properties, but they are always null. The beans are correctly configured in my xml. Any reason why?
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>
userrepository.java
@Repository("userRepository")
public class UserRepository extends
BaseRepository<User, Long> implements
IUserRepository {
@Autowired
public UserRepository(SessionFactory sessionFactory) {
super(sessionFactory);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我自己也遇到过这个。问题是,当您
在 Instance() 中执行操作时,您没有使用 Spring 来创建 RepositoryManager,因此您的实例不会发生依赖项注入(没有自动装配)。
解决方案是取消 Instance() 单例模式。如果你想坚持使用单例,那么就这样做
然后无论你在哪里需要存储库管理器,只需自动装配对它的引用(假设调用bean也由Spring管理!)
I just ran into this myself. The problem is that when you do
in Instance(), you are not using Spring to create RepositoryManager, and thus the dependency injection isn't happening for your instance (no autowiring).
The solution is to do away with the Instance() singleton pattern. If you want to insist on a Singleton, then do this
Then wherever you need the repository manager, just autowire in a reference to it (assuming the calling bean is also managed by Spring!)
请确保您的配置中有以下内容:
如果有,请发布您的配置 xml
Please make sure that you have the following in your config:
If you have it then post your configuration xml
实际上有一种非常优雅的方法可以鱼与熊掌兼得,即拥有一个同样由 Spring 管理的 JVM 单例。假设您有一个带有自动装配 bean 的纯 java 单例,如下所示:
您只需在应用程序上下文中添加以下行即可强制 Spring 管理此单例:
现在您的单例将具有
SomeSpringBean
自动装配的实例(如果在上下文中可用)。此外,这是对 Spring 单例 bean 的典型问题的“修复”,这些 bean 不是真正的 JVM 单例,因为它们是由 Spring 实例化的。使用上面的模式可以强制执行 JVM 级别的单例,即编译器强制执行的单例以及容器单例。
There is actually a very elegant way to have your cake and eat it, i.e., have a JVM singleton that's also Spring-managed. Say you have a pure java singleton with an autowired bean like this:
You can force Spring to manage this singleton simply by adding in your application context the following line:
Now your singleton will have an instance of
SomeSpringBean
autowired (if available in the context).Moreover, this is a 'fix' for the typical problem with Spring singleton beans that are not truly JVM singletons because they get instantiated by Spring. Using the pattern above enforces JVM level singleton, i.e., compiler enforced singleton, together with container singleton.
发生这种情况的原因是
您在 spring 上下文之外创建 POJO 的静态方法 Instance() 。
您可以通过将
添加到您的配置中来解决此问题,然后使用@Configurable
注释RepositoryManager
The reason this is happening is because of the static method
Instance()
you are creating the POJO outside of the spring context.
you can fix this, by adding
<context:spring-configured />
to your configuration, and then annotatingRepositoryManager
with@Configurable