我碰到一个比较纳闷的问题:
我定义了一个类为:
Java code
/**
@author zhanghg
*
*/
public class AcegiCacheManagerFactoryBean implements FactoryBean,InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
private AcegiCacheManager acegiCacheManager;
private AuthenticationService authenticationService;
private UserCache userCache;
private ResourceCache resourceCache;
public Object getObject() throws Exception {
return this.acegiCacheManager;
}
@SuppressWarnings("unchecked")
public Class getObjectType() {
return (this.acegiCacheManager != null ? this.acegiCacheManager.getClass() : AcegiCacheManager.class);
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
logger.info("Initializing SecurityCacheManager");
Assert.notNull(userCache,"userCache should not be null");
Assert.notNull(resourceCache,"resourceCache should not be null");
Assert.notNull(authenticationService,"Authentication Service should not be null");
//初始化缓存
List<Staff> users =authenticationService.getUsers();
for (Iterator iter = users.iterator(); iter.hasNext();) {
UserDetails user = (UserDetails) iter.next();
userCache.putUserInCache(user);
}
List<Resource> rescs =authenticationService.getResources();
for (Iterator iter = rescs.iterator(); iter.hasNext();) {
Resource resc = (Resource) iter.next();
resourceCache.putResourceInCache(resc);
}
//生成 acegiCacheManager
this.acegiCacheManager = new AcegiCacheManager(userCache,resourceCache);
}
//-------------setters-----------
public void setAcegiCacheManager(AcegiCacheManager acegiCacheManager) {
this.acegiCacheManager = acegiCacheManager;
}
@Required
public void setAuthenticationService(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
@Required
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
@Required
public void setResourceCache(ResourceCache resourceCache) {
this.resourceCache = resourceCache;
}
}
同时还定义了一个类为:
[code=Java]
/**
@author zhanghg
*
*/
public class AcegiCacheManager {
private UserCache userCache;
private ResourceCache resourceCache;
//rescTypeMapp 映射资源类型对应的资源的一对多关系,以便快速查找。
//如method类型对应哪些资源实例,url资源类型对应哪些资源实例
private Map<String,List<String>> rescTypeMapping;
//-----constructor using fields
@SuppressWarnings("unchecked")
public AcegiCacheManager(UserCache userCache, ResourceCache resourceCache) {
System.out.println("实例化SecurityManager");
this.userCache = userCache;
this.resourceCache = resourceCache;
// 获取所有的资源,以初始化 rescTypeMapping
rescTypeMapping = new HashMap<String,List<String>>();
List<String> resclist = resourceCache.getAllResources();
for (Iterator iter = resclist.iterator(); iter.hasNext();) {
String resString = (String) iter.next();
System.out.println("初始化SecurityCacheManager时取得资源信息的path:"+resString);
ResourceDetails resc = resourceCache.getResourceFromCache(resString);
System.out.println("输出该资源的type类型为:"+resc.getResourceType());
List<String> typelist = rescTypeMapping.get(resc.getResourceType());
if(typelist==null){
typelist = new ArrayList<String>();
rescTypeMapping.put(resc.getResourceType(), typelist);
}
typelist.add(resString);
}
System.out.println("输出最终的resTypeMapping信息:"+rescTypeMapping.size());
}
//-----get from cache methods
public UserDetails getUser(String username) {
return userCache.getUserFromCache(username);
}
public ResourceDetails getResourceFromCache(String resString) {
return resourceCache.getResourceFromCache(resString);
}
//-----remove from cache methods
public void removeUser(String username){
userCache.removeUserFromCache(username);
}
public void removeResource(String resString){
ResourceDetails rd = resourceCache.getResourceFromCache(resString);
List<String> typelist = rescTypeMapping.get(rd.getResourceType());
typelist.remove(resString);
resourceCache.removeResourceFromCache(resString);
}
//------add to cache methods
public void addUser(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, GrantedAuthority[] authorities){
User user = new User(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
addUser(user);
}
public void addUser(UserDetails user){
System.out.println("进来,添加user至缓存");
userCache.putUserInCache(user);
}
public void addResource(String resourceName,String resString, String resType, GrantedAuthority[] authorities){
Resource rd = new Resource(resourceName,resString, resType, authorities);
addResource(rd);
}
public void addResource(ResourceDetails rd){
List<String> typelist = rescTypeMapping.get(rd.getResourceType());
if(typelist==null){
typelist = new ArrayList<String>();
rescTypeMapping.put(rd.getResourceType(), typelist);
}
typelist.add(rd.getPath());
resourceCache.putResourceInCache(rd);
}
// ------renovate cache methods
public void renovateUser(String orgUsername, String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, GrantedAuthority[] authorities){
removeUser(orgUsername);
addUser(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
}
public void renovateUser(String orgUsername, UserDetails user){
removeUser(orgUsername);
addUser(user);
}
public void renovateResource(String resName,String orgResString,String resString, String resType, GrantedAuthority[] authorities ){
removeResource(orgResString);
addResource(resName,resString, resType, authorities);
}
public void renovateResource(String orgResString,ResourceDetails rd){
removeResource(orgResString);
addResource(rd);
}
//-------getters and setters-------------------
public void clearResources() {
rescTypeMapping = new HashMap<String,List<String>>();
resourceCache.removeAllResources();
}
public void setResourceCache(ResourceCache resourceCache) {
this.resourceCache = resourceCache;
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
/**
* 根据资源类型,在rescTypeMapping职工获取所有该类型资源的对应的resource string
* @param resType
* @return List
*/
public List<String> getResourcesByType(String resType) {
return rescTypeMapping.get(resType);
}
/**
* 获取所有资源的对应的resource string
* @return
*/
public List<String> getAllResources(){
return resourceCache.getAllResources();
}
/**
* 获取所有用户实例对应的user name
* @return
*/
@SuppressWarnings("unchecked")
public List<String> getAllUsers(){
EhCacheBasedUserCache ehUserCache = (EhCacheBasedUserCache)userCache;
return ehUserCache.getCache().getKeys();
}
}
[/code]
同时我的一个类:StaffManager中要用到AcegiCacheManager类
public class StaffManager {
// 统一定义所有HQL
private static final String QUERY_ADMIN_HQL = "select staff from Staff staff join staff.roles as role where role.roleName=?";
private final Logger logger = LoggerFactory.getLogger(StaffManager.class);
//自动装配该bean的属性
@Autowired
private StaffDao staffDao;
@Autowired
private RoleDao roleDao;
@Autowired
private PrivilegeDao privilegeDao;
@Autowired
private ResourceDao resourceDao;
private AcegiCacheManager acegiCacheManager;
通过@Reqiured进行了注解.
其中我在配置文件配置了bean:
但是为什么staffManager当中,取到的acegiCacheManager老是null呢?
当然通过上下文的getBean("acegiCacheManager")是可以取到这个类的,不是null
[b]问题补充:[/b]
楼上的还还是不明白:
如果通过在xml文件中注册bean:
那么我应该在staffManager中怎样写才能取得不为null啊?
而如果我通过@Component("acegiCacheManager")进行注解,
我在staffManager中进行@Autowired,但是为什么提示:
Could not autowire field: private com.sdcncsi.security.cache.manager.AcegiCacheManager,com.sdcncsi.service.sys.StaffManager注解错误?
我该 怎样做?
另外factory bean会在服务启动时自动的启动这个bean吗?
而AcegiCacheManager是在AcegiCacheManagerFactoryBean中使用的,但是如果在其它类中我们怎样来引用它,直接注入AcegiCacheManager吗?但是这个类没有默认构造方法,不能实例化.
我现在都晕了,搞的好头大,请各位大人帮忙啊.
[b]问题补充:[/b]
@Autowired
private ResourceDao resourceDao;
@Autowired
private AcegiCacheManager acegiCacheManager;
我试了后不行:
1)我的配置文件中配置了:
它 是指向工厂类的,这样在启动的时候可以初始化信息.
后来,我把AcegiCacheManagerFactoryBean进行了@Component("acegiCacheManager")
并且在StaffManager中对 AcegiCacheManager acegiCacheManager 启用@Autowired,
提示:Could not autowire field:
rror creating bean with name 'acegiCacheManager': FactoryBean which is currently in creation returned null from getObject
我该如何做才对啊?
public class StaffManager {
// 统一定义所有HQL
private static final String QUERY_ADMIN_HQL = "select staff from Staff staff join staff.roles as role where role.roleName=?";
private final Logger logger = LoggerFactory.getLogger(StaffManager.class);
//自动装配该bean的属性
@Autowired
private StaffDao staffDao;
@Autowired
private RoleDao roleDao;
@Autowired
private PrivilegeDao privilegeDao;
@Autowired
private ResourceDao resourceDao;
private AcegiCacheManager acegiCacheManager;
这个bean你还是用xml配置文件的方式配置,不要用@Autowired,
为什么会报这个错Could not autowire field: private com.sdcncsi.security.cache.manager.AcegiCacheManager,
那是因为StaffManager 必须设置成依赖于
这个bean初始化属性都设置成功之后,acegiCacheManager这个属性才不为null,不然的话,
public Object getObject() throws Exception {
return this.acegiCacheManager;
} 这个工厂bean的这个方法调用得到的就是null
你改用xml配置,设置一下依赖关系
@Autowired
private ResourceDao resourceDao;
private AcegiCacheManager acegiCacheManager;
你是不是在应该这样写啊
@Autowired
private ResourceDao resourceDao;
[color=red]@Autowired
private AcegiCacheManager acegiCacheManager; [/color]
你没有通过设置@Autowired 来实现自动注入。
通过getContext("")能取到也说明你已在配置文件中进行配置。
按楼上的就可以解决。