`
y806839048
  • 浏览: 1080027 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring的FactoryBean

阅读更多

以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

  例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。

 

shiro中就利用facoryBean的getObject()返回Ini.Section对象注入动态权限

 

 

/**

 * my factory bean<p>

 * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出

 * @author daniel.zhao

 *

 */

public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean {

 

    private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class);

    

    private String interfaceName;

    

    private Object target;

    

    private Object proxyObj;

    

    @Override

    public void destroy() throws Exception {

        logger.debug("destroy......");

    }

 

    @Override

    public void afterPropertiesSet() throws Exception {

        proxyObj = Proxy.newProxyInstance(

                this.getClass().getClassLoader(), 

                new Class[] { Class.forName(interfaceName) }, 

                new InvocationHandler() {

                    

            @Override

            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                logger.debug("invoke method......" + method.getName());

                logger.debug("invoke method before......" + System.currentTimeMillis());

                Object result = method.invoke(target, args);

                logger.debug("invoke method after......" + System.currentTimeMillis());

                return result;

            }

            

        });

        logger.debug("afterPropertiesSet......");

    }

 

    @Override

    public Object getObject() throws Exception {

        logger.debug("getObject......");

        return proxyObj;

    }

 

    @Override

    public Class<?> getObjectType() {

        return proxyObj == null ? Object.class : proxyObj.getClass();

    }

 

    @Override

    public boolean isSingleton() {

        return true;

    }

 

    public String getInterfaceName() {

        return interfaceName;

    }

 

    public void setInterfaceName(String interfaceName) {

        this.interfaceName = interfaceName;

    }

 

    public Object getTarget() {

        return target;

    }

 

    public void setTarget(Object target) {

        this.target = target;

    }

 

    public Object getProxyObj() {

        return proxyObj;

    }

 

    public void setProxyObj(Object proxyObj) {

        this.proxyObj = proxyObj;

    }

 

}

 

 

XML-Bean配置如下

1 <bean id="fbHelloWorldService" class="com.ebao.xxx.MyFactoryBean">
2     <property name="interfaceName" value="com.ebao.xxx.HelloWorldService" />
3     <property name="target" ref="helloWorldService" />
4 </bean>

 

@RunWith(JUnit4ClassRunner.class)

@ContextConfiguration(classes = { MyFactoryBeanConfig.class })

public class MyFactoryBeanTest {

 

    @Autowired

    private ApplicationContext context;

    

    /**

     * 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理

     * 从ApplicationContext中获取自定义的FactoryBean

     * context.getBean(String beanName) ---> 最终获取到的Object是FactoryBean.getObejct(), 

     * 使用Proxy.newInstance生成service的代理类

     */

    @Test

    public void testFactoryBean() {

        HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService");

        helloWorldService.getBeanName();

        helloWorldService.sayHello();

    }

 

}

 

 

 

shiro示例:

 

 

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

<property name="securityManager" ref="securityManager" />

<property name="loginUrl" value="/login" />

<!--<property name="successUrl" value="/login/auth" />-->

<!--<property name="successUrl" value="http://116.236.184.238:8007/" />-->

<property name="successUrl" value="${shiro.in.url}" />

<!--<property name="successUrl" value="http://10.100.82.100:8126/" />-->

<property name="unauthorizedUrl" value="/login" />

<property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />

<property name="filters">

<map>

<entry key="authc" value-ref="authenticationFilter" />

<entry key="role" value-ref="roleAuthorizationFilter" /> 

</map>

</property>

</bean>

 

 

<bean id="chainDefinitionSectionMetaSource" class="com.houbank.incoming.web.shrio.ChainDefinitionSectionMetaSource">

  

    <property name="filterChainDefinitions">

<value>

/flex/rbac/preLogin.action=authc

/j_acegi_security_check=authc

/flex/uifrm/index.jsp=authc

/flex/rbac/getLoginIndex.action=authc

/logout = logout

/user/logout.action = logout

<!-- /** = authc  -->

        </value>  

    </property>  

   </bean>

 

<bean id="myShiroFilterFactory" class="com.houbank.incoming.web.shrio.MyShiroFilterFactory">

 

<property name="filterChainDefinitions">

<value>

/flex/rbac/preLogin.action=authc

/j_acegi_security_check=authc

/flex/uifrm/index.jsp=authc

/flex/rbac/getLoginIndex.action=authc

/logout = logout

/user/logout.action = logout

<!-- /** = authc  -->

</value>

</property>

 

 

</bean>

 

 

 

package com.houbank.incoming.web.shrio;

 

import com.alibaba.dubbo.config.annotation.Reference;

import com.houbank.basic.util.response.BaseResponse;

import com.houbank.incoming.api.FinancialSalesFuncFacade;

import com.houbank.incoming.api.FinancialSalesRoleFacade;

import com.houbank.incoming.model.condition.FinancialSalesFuncCondition;

import com.houbank.incoming.model.condition.FinancialSalesRoleCondition;

import com.houbank.incoming.model.condition.FinancialSalesUserRoleCondition;

import com.houbank.incoming.model.domain.FinancialSalesFunc;

import com.houbank.incoming.model.domain.FinancialSalesFuncRole;

import com.houbank.incoming.model.domain.FinancialSalesRole;

import com.houbank.incoming.web.controller.FinancialSalesUserController;

import org.apache.shiro.config.Ini;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;

 

import java.util.*;

 

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{

 

 

    private String filterChainDefinitions;

    

 

    @Autowired(required=false)

    private RedisTemplate redisTemplate;

 

    @Reference

    private FinancialSalesFuncFacade financialSalesFuncFacade;

 

    @Reference

    private FinancialSalesRoleFacade financialSalesRoleFacade;

    

    /**

     * 默认premission字符串

     */

    public static final String PREMISSION_STRING="perms[\"{0}\"]";

    

   

    public Ini.Section getObject() throws BeansException {

 

        //获取所有Resource

    Map<String,String> a = new HashMap<String,String>();

    try {

 

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

        return  getSectionService(filterChainDefinitions) ;

    }

 

public Ini.Section getSectionService(String filterChainDefinitions) {

List<FinancialSalesFuncRole> list =new ArrayList<FinancialSalesFuncRole>();

        List<FinancialSalesFuncRole> listAll =new ArrayList<FinancialSalesFuncRole>();

        FinancialSalesUserRoleCondition financialSalesRoleCondition =new FinancialSalesUserRoleCondition();

        FinancialSalesFuncCondition financialSalesFuncCondition =new FinancialSalesFuncCondition();

        list =  financialSalesRoleFacade.selectAll();

        List<Map> branchArr = financialSalesRoleFacade.getRoleFuncUrl(financialSalesRoleCondition);//this.baseService.queryForJDBCList(sql);

        BaseResponse<List<FinancialSalesFunc>> listfuncs=   financialSalesFuncFacade.selectAll(financialSalesFuncCondition);

        List<FinancialSalesFunc>  listfunc =(List<FinancialSalesFunc>)listfuncs.getData();

        Set<String> itms= new HashSet<String>();

        Set<String> itmls= new HashSet<String>();

        for (Iterator<Map> it1 = branchArr.iterator(); it1.hasNext();) {

        Map resource = (Map)it1.next();////角色菜单信息

        itmls.add(resource.get("funcId")+"");

        }

        Ini ini = new Ini();

        ini.load(filterChainDefinitions);

        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);

        Map<String,Set<String>> mapr = new HashMap<String,Set<String>>();

        Set<String> roleIds=null;

        Set<String> mlroleIds=null;

        if(list!=null&&list.size()>0){

//双重循环讲角色和对应的菜单对应

 

            for(int i = 0; i < listfunc.size(); i++){

                FinancialSalesFunc r = (FinancialSalesFunc)listfunc.get(i);

        roleIds=new HashSet<String>();

            mlroleIds=new HashSet<String>();

             for (Iterator<Map> it = branchArr.iterator(); it.hasNext();) {//遍历角色菜单

            Map resource = it.next();

        if(r.getId().equals(resource.get("funcId"))){

            //如果不为空值添加到section中

            roleIds.add(resource.get("roleId")+"");

             }

        }

            if(!"".equals(r.getUrl()) && null!=r.getUrl()){

         mapr.put(r.getUrl()+"", roleIds);

             }

        }

        }

        StringBuffer au=null;

        String st="";

//匹配到的转化为要求格式

        for(Map.Entry<String, Set<String>> en:mapr.entrySet()){

        au = new StringBuffer();

        au.append("authc,role[");

        for(String a :en.getValue()){

        au.append("\""+a+"\",");

        }

        String strau=au.substring(0,au.lastIndexOf(","));

            if(strau.contains(",role[")){

                strau+="]";

            }

 

        st+=en.getKey()+">>>>"+strau+"\n";

          section.put(en.getKey(),strau);

        }

        System.out.println(st);

return section;

}

 

    /**

     * 通过filterChainDefinitions对默认的url过滤定义

     * 

     * @param filterChainDefinitions 默认的url过滤定义

     */

    public void setFilterChainDefinitions(String filterChainDefinitions) {

        this.filterChainDefinitions = filterChainDefinitions;

    }

 

    public Class<?> getObjectType() {

        return this.getClass();

    }

 

    public boolean isSingleton() {

        return false;

    }

 

    public FinancialSalesFuncFacade getFinancialSalesFuncFacade() {

        return financialSalesFuncFacade;

    }

 

    public void setFinancialSalesFuncFacade(FinancialSalesFuncFacade financialSalesFuncFacade) {

        this.financialSalesFuncFacade = financialSalesFuncFacade;

    }

 

    public FinancialSalesRoleFacade getFinancialSalesRoleFacade() {

        return financialSalesRoleFacade;

    }

 

    public void setFinancialSalesRoleFacade(FinancialSalesRoleFacade financialSalesRoleFacade) {

        this.financialSalesRoleFacade = financialSalesRoleFacade;

    }

}

 

分享到:
评论

相关推荐

    spring的FactoryBean增强我们的目标对象.rar

    通过FactoryBean在获取目标类的时间我们将增强的代理类给返回,使得我们调用方法的时间使用的代理类来增强,如果需要继续使用未代理的对象,则直接@Autowired 注入使用.

    SpringFactoryBean:spring FactoryBean的样本,在运行时在两个bean之间进行更改

    spring FactoryBean的小样本,如何在运行时在两个bean之间进行切换。

    详解Spring中的FactoryBean

    本篇文章主要介绍了Spring中的FactoryBean,如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean

    spring中的FactoryBean代码示例

    主要介绍了spring中的FactoryBean代码示例,涉及FactoryBean的实现等相关内容,具有一定参考价值,需要的朋友可以了解下。

    spring中FactoryBean中的getObject()方法实例解析

    主要介绍了spring中FactoryBean中的getObject()方法实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    spring源码解析之FactoryBean相关测试代码demo

    spring源码解析之FactoryBean相关测试代码demo,文章中也有相关代码

    Spring中的FactoryBean.rar

    Spring中的FactoryBean.rar

    简单了解Spring中BeanFactory与FactoryBean的区别

    主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    spring:这是Spring框架研究

    spring This is spring framework study ...八、使用spring FactoryBean技术模拟mybatis MapperScan注解 https://github.com/AvengerEug/spring/tree/develop/implement-mapperscan 九、mybatis源码学习 ...

    Spring基于ProxyFactoryBean创建AOP代理

    主要介绍了Spring基于ProxyFactoryBean创建AOP代理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    FactoryBean代码最简实现

    这篇代码主要适用于我的博客,用来帮助理解Spring配置文件+FactoryBean的实例化过程。注意,这里是FactoryBean,而不是BeanFactory,下载资源要看清楚哈。

    深入了解Spring中的FactoryBean

    主要介绍了深入了解Spring中的FactoryBean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring中BeanFactory与FactoryBean接口的区别详解

    主要给大家介绍了关于Spring中BeanFactory与FactoryBean接口的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    spring如何通过FactoryBean配置Bean

    主要介绍了spring如何通过FactoryBean配置Bean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring BeanFactory和FactoryBean区别解析

    主要介绍了Spring BeanFactory和FactoryBean区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    spring4示例代码

    spring-2 演示了外部配置文件的引入(connection),spel(spring el)表达式 ,静态工厂方式及实例工厂方式及factorybean方式创建bean, spring的生命周期及BeanPostProcessor的使用,注解方式创建bean 及使用...

    spring的详细介绍

    Spring介绍 1. Spring 2. 使用spring的主要目的 3. Spring的模块 Ejb容器(以前是) Ioc容器(现在的控制权) 控制反转Ioc(Invertion of control)依赖注入(Dependency Injection) ...13. 接口FactoryBean的使用

    精通Spring整合MyBatis:架构师的实践指南

    Spring和MyBatis的整合是Java...Spring使用FactoryBean来创建特定类型的bean,例如MyBatis的Mapper接口的动态代理实例。BeanDefinitionRegistry则用于注册这些动态生成的bean,确保它们可以被Spring容器识别和管理。

    factory-bean-demo.7z

    spring 自定义 FactoryBean 样例工程,可以通过这个工程通过实现FactoryBean来扩展Spring容器

    高级开发spring面试题和答案.pdf

    BeanFactory和FactoryBean有什么区别; Spring中用到的设计模式; SPI 机制(Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制), 很多地方有用到: AOP Spring的AOP的底层实现原理; ...

Global site tag (gtag.js) - Google Analytics