在spring中自己实现AOP编程

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

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

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

 

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

 

目标对象 IUserDao与UserDao

 

 

public interface IUserDao {
	void save();
	
	void find();
}

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

	@Override
	public void find() {
		System.out.println("查询");
	}

}

 

关注点代码类

@Component
public 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中的关注点代码注入到多个目标对象的业务代码中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值