以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`是一个非常重要的接口,它允许我们自定义对象的创建方式。这个接口使得我们可以实现自己的工厂逻辑,返回一个完全初始化、配置好的对象,甚至可以是带有额外增强功能的对象,比如代理...
在Spring框架中,`FactoryBean`是一个非常重要的接口,它为Spring容器提供了更高级别的抽象,使得我们可以自定义Bean的创建过程。当一个Bean的初始化需要处理复杂的逻辑、依赖其他多个Bean,或者需要进行特殊处理时...
Spring 中 FactoryBean 中的 getObject() 方法实例解析 Spring 框架中 FactoryBean 是一个非常重要的概念,它提供了一种创建和管理 Bean 的机制。在 Spring 中,FactoryBean 是一个特殊的 Bean,它可以创建其他 ...
Spring中的FactoryBean代码示例 在Spring框架中,FactoryBean是一种特殊的Bean,它可以生成其他Bean的实例。今天我们来了解一下FactoryBean的实现和使用。 首先,让我们从SessionFactory说起。在使用SSH集成开发时...
在Spring框架中,`FactoryBean`是一个非常重要的接口,它允许开发者自定义bean的创建逻辑。这个接口使得Spring容器能够根据特定的工厂方法来实例化对象,而不是通过默认的构造函数。`SpringFactoryBean`的例子在处理...
在Spring框架中,`FactoryBean`是一个非常关键的接口,它允许我们自定义对象的创建方式,这在处理复杂依赖关系或需要特殊初始化逻辑时尤为有用。本篇将通过一个测试代码示例来深入解析`FactoryBean`的工作原理及其在...
在Spring框架中,FactoryBean是一个非常重要的概念,它允许我们自定义对象的创建方式,提供了扩展Spring IoC容器的能力。FactoryBean是Spring提供的一种特殊类型的bean,它不仅仅是一个普通的对象,还是一个工厂,...
简单了解Spring中BeanFactory与FactoryBean的区别 Spring框架中有两个非常关键的接口:BeanFactory和FactoryBean。虽然它们的名字相似,但它们的作用和实现机制却有很大的不同。 BeanFactory是Spring IoC容器的...
Spring 基于 ProxyFactoryBean 创建 AOP 代理 ProxyFactoryBean 是 Spring 中用于创建 AOP 代理的重要工具类,它提供了完整的控制能力,可以生成指定的内容。下面将详细介绍 ProxyFactoryBean 的使用方法和 Spring...
在Spring框架中,`FactoryBean`是一个非常重要的概念,它为Spring容器提供了自定义对象创建的能力。本篇我们将深入探讨`FactoryBean`的最简实现及其在Spring配置文件中的使用,帮助你理解其实例化过程。 `...
spring This is spring framework study ...八、使用spring FactoryBean技术模拟mybatis MapperScan注解 https://github.com/AvengerEug/spring/tree/develop/implement-mapperscan 九、mybatis源码学习 ...
深入了解Spring中的FactoryBean FactoryBean是一个非常重要的概念,在Spring框架中扮演着核心角色。它提供了一种灵活的方式来创建和管理对象实例。在本篇文章中,我们将深入了解FactoryBean的概念和应用。 一、...
在Spring框架中,`FactoryBean`接口是一个非常重要的组件,它允许我们自定义Bean的创建逻辑,这在处理复杂对象的实例化或者需要特定初始化步骤时尤其有用。本笔记将详细探讨如何通过实现`FactoryBean`接口来创建Bean...
Spring 通过 FactoryBean 配置 Bean 在 Spring 框架中,FactoryBean 是一种特殊的 Bean,它可以实现复杂的 Bean 实例化逻辑。通过 FactoryBean,我们可以将复杂的实例化逻辑封装起来,使得 Bean 的配置更加灵活和...
在Spring框架中,BeanFactory和FactoryBean是两个重要的接口,它们各自扮演着不同的角色,但都与Spring容器的管理和创建对象密切相关。 **BeanFactory接口**是Spring容器的基础,它是整个Spring IoC(Inversion of ...
Spring BeanFactory和FactoryBean的区别解析 Spring框架中,BeanFactory和FactoryBean是两个非常重要的概念,它们都是Spring IoC容器的核心组件。今天,我们将深入探讨这两个概念之间的区别和联系。 首先,让我们...
Spring 提供了多种方式来实例化和管理 Bean,包括通过构造方法、简单工厂模式、FactoryBean 等。 Spring 还提供了多种范围的 Bean,包括 singleton、prototype 等。 Spring 的 IoC 容器是框架的核心组件,它负责...
Spring 中的 BeanFactory 和 FactoryBean BeanFactory 是 Spring 框架中的核心组件之一,负责管理 Bean 的生命周期,包括实例化、配置和注入对象之间的关系。它是 Spring IOC(控制反转)容器的核心组件,提供了...
在Spring框架中,`FactoryBean`是一个至关重要的接口,它为Spring容器提供了创建对象的自定义逻辑。`FactoryBean`的使用使得我们可以控制对象的创建过程,甚至可以在对象被Spring管理的同时,添加额外的初始化或者...
4. **MapperFactoryBean**:它是 Spring 的 FactoryBean,用于实例化 Mapper 接口并注入到 Spring 容器。这样,我们可以在 Spring 环境中通过 DAO 接口直接调用 SQL 方法,而无需关心实现细节。 5. **Transaction ...