os586 2009-04-18 00:52 采纳率: 0%
浏览 439
已采纳

Spring FactoryBean的使用

我碰到一个比较纳闷的问题:
我定义了一个类为:

Java code
/**

  • AcegiCacheManagerFactoryBean 负责初始化缓存后生成AcegiCacheManager
  • 调用 authenticationService 来获取资源和用户实例,并加入UserCache 和 ResourceCache 中
  • @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]
/**

  • AcegiCacheManager是对缓存进行统一管理,以屏蔽其它类对缓存的直接操作
  • 对缓存中的用户和资源进行初始化、增、删、改、清空等操作
  • @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]

lovewhzlq说通过这样改定就可以:

@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

我该如何做才对啊?

  • 写回答

3条回答 默认 最新

  • wanghaolovezlq 2009-04-18 13:09
    关注

    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配置,设置一下依赖关系

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入