Spring3之AOP动态代理的实现

简介

动态代理是通过指一个代理对象来创建需要的业务对象,然后在这个代理对象中统一进行各种需求的处理;使用动态代理需要如下 4 个步骤:

(1) 创建一个类,实现 InvocationHandler 接口

(2) 创建代理对象

(3) 创建一个方法来生成对象,这个方法的参数是要代理对象

(4) 有了代理对象后,不管这个代理对象执行什么方法,都会调用 Invoke 方法

实现步骤

  1. 创建实体类 LogProxy.class,实现 InvocationHandler 接口,并添加如下代码
// 1.创建实体类, 实现 InvocationHandler 接口 
public class LogProxy implements InvocationHandler {    // 2.创建一个代理对象
    private Object target;
    // 3.创建一个方法生成对象, 该方法的参数就是要代理的对象, 返回值就是被代理的对象
    public static Object getInstance(Object object) {
        // 3.1 创建 LogProxy 对象
        LogProxy proxy = new LogProxy();
        // 3.2 设置这个代理对象
        proxy.target = object;
        // 3.3 通过 Proxy 对象创建代理对象, 第一个参数是要代理对象的 ClassLoader; 
        // 第二个参数是要代理对象实现的所有接口; 
        // 第三个参数是实现类 InvocationHandler 的对象
        Object result = Proxy.newProxyInstance(object.getClass().getClassLoader(),
            object.getClass.getInterfaces(), proxy);
            // 此时的 result 就是一个代理对象, 代理的就是 object
        return result;
    }
    // 有了代理对象后,不管这个代理对象执行什么方法, 都会调用下面这个 invoke 方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(new Date() + " ---> 进行了操作: " + method);
        Object object = method.invoke(target, args);
        return object;
    }
}
  1. 在 beans.xml 中添加如下配置,注册一个 Bean,通过这个代理的 Bean 去代理 UserDao
<!-- 设置代理对象 proxyUserDao, 注意此处 getInstance 是静态方法, userDao 是关联的对象 -->
<bean name="proxyUserDao" class="com.duzimei.blog.proxy.LogProxy" factory-method="getInstance">
     <!-- 指定 getInstance() 方法的参数, 即要被代理的对象 -->  
     <constructor-arg ref="userDao"/>
</bean>
  1. 在 UserService.class 中将注入的对象指定为代理对象:proxyUserDao 即可
@Service
public class UserService implements IUserService {    
    private IUserDao userDao;    
   
    @Resource(name="proxyUserDao")
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }
}

使用注解优化输出

  1. 新建一个 Annotation:LogInfo,添加如下代码
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {
    public String value() default "";
}

  1. 将该注解添加在方法上,并添加要输出的日志信息
public interface IUserDao {
    @LogInfo("添加 User")
    public void add(User user);
    @LogInfo("删除 User")
    public void delete(int id);
}
  1. 修改 LogProxy.class 中的 invoke 方法
// 有了代理对象后,不管这个代理对象执行什么方法, 都会调用下面这个 invoke 方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(method.isAnnotationPresent(LogInfo.class)) {
        LogInfo logInfo = method.getAnnotation(LogInfo.class);
        System.out.println(new Date() + " ---> 进行了操作: " + logInfo.value());
    }
    Object object = method.invoke(target, args);
    return object;
}

测试一下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值