Spring之FactoryBean接口

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

    下面简单的分享下利用FactoryBean接口实现一个类似aop的功能

1.首先创建一个需要aop的类

public interface HelloWorldService {

    void sayHelloWorld(String name);

    void sayGood(String name);

    void smile(String name);
}
2.实现上述接口,代码略

3.定义aop接口类

public interface HelloWorldAop {
    /**
     * 在执行方法之前执行的代码
     */
    void doBefore(Object... args);

    /**
     * 在执行方法之后执行的代码
     */
    void doAfter(Object... args);

}

4.写一个或多个实现类去实现上述接口,具体几个实现类取决于不同的业务需求

public class HelloWorldAopImpl implements HelloWorldAop {

    public static final Logger log = LoggerFactory.getLogger(HelloWorldAopImpl.class);

    /*
     * (non-Javadoc)
     * @see com.dingwang.aop.HelloWorldAop#doBefore()
     */
    public void doBefore(Object... args) {
        log.info("do before the method sayHello for " + args[0]);
    }

    /*
     * (non-Javadoc)
     * @see com.dingwang.aop.HelloWorldAop#doAfter()
     */
    public void doAfter(Object... args) {
        log.info("do after the method sayHello for " + args[0]);
    }

}
5.核心部分,创建代理类HWFactoryBean,代理类实现FactoryBean和InitializingBean接口

/** 被代理对象实现的接口 */
    private String                                   interfaceName;

    /** 被代理的对象 */
    private Object                                   target;

    /** 生成的代理对象 */
    private Object                                   proxyObj;

    /** 要处理的代理对象中的方法,若为空,则处理所有方法 */
    private Map<String/* 代理对象的方法名 */, HelloWorldAop> proxyMethodMap;

public void afterPropertiesSet() throws Exception {
        proxyObj = Proxy.newProxyInstance(this.getClass().getClassLoader(),
                new Class[] { Class.forName(interfaceName) }, new InvocationHandler() {

                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;
                        String methodName = method.getName();
                        log.info("method:" + method.getName());
                        //判断此方法是否需要做处理
                        if (proxyMethodMap != null && proxyMethodMap.containsKey(methodName)) {
                            //做before处理
                            proxyMethodMap.get(methodName).doBefore(args);
                            result = method.invoke(target, args);
                            //做after处理
                            proxyMethodMap.get(methodName).doAfter(args);
                        } else {
                            result = method.invoke(target, args);
                        }

                        return result;
                    }
                });
        log.info("afterPropertiesSet............");
    }
上述片段可以看出代理类 HWFactoryBean实现InitializingBean,初始化时会去创建一个实例,这个实例是对被代理的类的包装,加了doBefore和doAfter处理,然后将其赋值给proxyObj,而对于实现FactoryBean接口的类,在根据beanId调用的时候,返回的对象实际上是getBoject(..)返回的对象,即proxyObj,从而实现对HelloWorldService中方法的织入

6.调用实例

public static void main(String[] args) throws Exception {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "classpath:spring-bean.xml" });
        HelloWorldService hw = (HelloWorldService) context.getBean("proxyHW");
        log.info("-----------------华丽的分割线-------------------------");
        hw.sayHelloWorld("LiuBei");
        log.info("-----------------华丽的分割线-------------------------");
        hw.sayGood("CaoCao");
        log.info("-----------------华丽的分割线-------------------------");
        hw.smile("SunQuan");
        HWFactoryBean hb = (HWFactoryBean) context.getBean("&proxyHW");
        log.warn(hb.getClass().getName());

    }
7.配置

<bean id="helloWorldService" class="com.dingwang.FactoryBean.Impl.HelloWorldServiceImpl"></bean>
	
	<bean id="goodByeAop" class="com.dingwang.aop.Impl.GoodByeAopImpl"></bean>
	<bean id="helloWorldAop" class="com.dingwang.aop.Impl.HelloWorldAopImpl"></bean>
	
	<bean id="proxyHW" class="com.dingwang.FactoryBean.HWFactoryBean">
		<property name="interfaceName" value="com.dingwang.FactoryBean.HelloWorldService"></property>
		<property name="target" ref="helloWorldService"></property>
		<property name="proxyMethodMap">
		<!-- key: -->
			<map>
				<entry key="sayGood">
					<ref bean="goodByeAop"/>
				</entry>
				<entry key="sayHelloWorld">
					<ref bean="helloWorldAop"/>
				</entry>
			</map>
		</property>
	</bean>


输出:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值