在spring中自己实现AOP编程

来源:互联网 发布:杭州行知小学校区 编辑:程序博客网 时间:2024/06/05 04:03

首先明确两个概念:业务代码和关注点代码

业务代码就是目标对象中执行的特有方法。

关注点代码是多个不同类别的目标对象中所存在的相同代码。

 

AOP编程的目的是分离目标对象的业务代码与关注点代码,使得关注点代码只写一次,而在执行业务代码的时候会动态植入关注点代码。

 

目标对象 IUserDao与UserDao

public interface IUserDao {void save();void find();}// 目标对象public class UserDao implements IUserDao{@Overridepublic void save() {System.out.println("模拟: 保存用户!");}@Overridepublic void find() {System.out.println("查询");}}

关注点代码类

@Componentpublic class MyAOP {    //写关注点代码 关注点代码只写一次,之后通过代理对象动态植入到目标对象的业务代码中    public void beginTransaction(){        System.out.println("开启事务..");    }    public void commit(){        System.out.println("提交事务..");    }}

代理工厂

public class ProxyObjectFactory {    /**     * 生成动态代理对象     * @param target 目标对象     * @param MyAop  提供关注点代码的对象     * @return     */    public Object getProxyInstance(final Object target, final MyAOP MyAop){        Object proxyInstance = Proxy.newProxyInstance(                target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                new InvocationHandler() {                    @Override                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                        String methodName = method.getName();                        Object result = null;                        if("save".equals(methodName)){                            MyAop.beginTransaction();                            result = method.invoke(target, args);                            MyAop.commit();                        }else{                            result = method.invoke(target, args);                        }                        return result;                    }                }        );        return proxyInstance;    }}

applicationContext中配置

    <!--myaop工厂方法生成代理对象-->    <bean id="proxyFactory" class="hfi.bellychang.myaop.ProxyObjectFactory"/>    <bean id="proxyInstance" factory-bean="proxyFactory" factory-method="getProxyInstance">        <constructor-arg index="0" ref="userDao"/>        <constructor-arg index="1" ref="myAOP"/>    </bean>

注意其中注入对象的方式,使用了工厂方法注入方式。

测试

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:/applicationContext.xml")public class AppTest {    @Resource    IUserDao proxyInstance;    @Test    public void testMyaop() {        //未加代理之前 只执行目标对象的业务代码        IUserDao userDao = new UserDao();        userDao.save();        userDao.find();        //使用代理对象 将只写一次的关注点代码动态植入到目标对象的业务代码中        //        proxyInstance.save();        proxyInstance.find();    }}
可以在applicationContext中为多个不同类别的目标对象配置相应的代理对象,就可以实现将MyAOP中的关注点代码注入到多个目标对象的业务代码中。

原创粉丝点击