java动态代理

来源:互联网 发布:linux添加路由命令 编辑:程序博客网 时间:2024/05/17 23:33

public interface IUserManager { //接口

 public void add(String userName);
 public void delete(String userName);
 public String query(String userName);
}

----------------

public class UserManagerImpl implements IUserManager {//实现类

 public void add(String userName) {
  System.out.println("UserManagerImpl add");
 }

 public void delete(String userName) {
  System.out.println("UserManagerImpl delete");
 }

 public String query(String userName) {
  System.out.println("UserManagerImpl query");
  return userName;
 }

}

----------------静态代理

//SaticProxy静态代理类必须实现接口,代理类也必须注入目标接口
public class SaticProxy implements IUserManager {
 private IUserManager iUserManager;
 //注入目标接口
 public SaticProxy(IUserManager iUserManager){
  this.iUserManager = iUserManager;
 }
 public void add(String userName) {
  checkSecury();
  iUserManager.add("wangwu");
 }

 public void delete(String userName) {
  checkSecury();
  iUserManager.delete("wangwu");
 }

 public String query(String userName) {
  checkSecury();
  return iUserManager.query(userName);
 }
   //操作每个方法前 必须进行检查 也就是调用下面这个方法
 private void checkSecury(){
  System.out.println("checkSecury");
 }
}

---------测试

public static void main(String[] args) {
  //IUserManager iuser = new SaticProxy(new UserManagerImpl());
  //iuser.add("zhangsan");
  }

----------------动态代理

// 由于静态代理只为实现类的一个接口服务,并在每个方法上都调用checkSecury(),有点麻烦
//动态代理是在调用方法时候动态的加上checkSecury
public class DynamicProxy implements InvocationHandler {//实现jdk封装的InvocationHandler接口
 private Object targetObject;//目标实现类
 public Object createProxyObject(Object targetObject){//接收目标实现类并返回代理类
  this.targetObject = targetObject;
  //反回代理类,底层封装的代理类也实现了和目标类一样的接口
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), //目标实现类加载器
    targetObject.getClass().getInterfaces(),// //目标实现类所实现的接口
    this);//调用当前对象
 }
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  checkSecury();//检查
  //当前对象的方法调用  ret是调用方法后返回值
  Object ret = method.invoke(targetObject, args);//targetObject目标对象 args当前方法接收的参数
  return ret;
 }
 //调用方法前的检查
 private void checkSecury(){
  System.out.println("checkSecury");
 }
}
------------------测试

public static void main(String[] args) {
  DynamicProxy dp = new DynamicProxy();//动态代理对象创建
  IUserManager iuer = (IUserManager)dp.createProxyObject(new UserManagerImpl());//创建代理 传入参数目标对象 返回代理对象(代理对象也实现了目标对象实现的接口,所以也就是返回了接口)
  iuer.add("zhangsan");
 }

/** 
       aop主要针对POJO的声明式事务,底层实现使用了jdk的动态代理
       代理:代理类实现了目标接口,调用时调用代理对象,合格了在调目标对象,不合格不让调目标对象。
       静态代理能能为谋一个类服务,动态代理能为所有类服务
       动态代理实现invocationHandler
       总结:代理的优点:当改变代码时候,不改变目标对象的代码,只改变代理类的代码,这样对客户端不影响
  */
--------------------------

 aop是横向的,横切性的关注点(checkSecury)叫做cross cutting concern,对这个关注点模块化(DynamicProxy)叫做aspect,关注点的(checkSecury)
            具体实现(System.out.println("checkSecury"))叫做advice(包括before advice,after advice)。
            什么样的方法(add,delete,query)调用该关注点叫做pointcut(add*),意味着addUer就可以调用advice,这叫做joinPoint

 

 cross cutting concern:是一种独立服务,遍布系统的处理流程中
            aspact:对横切性关注点的模块化
            advice:横切性关注点的具体实现
            pointcut:定义了advice到哪些joinPoint上,对spring讲就是对方法的调用
            joinpoint:调用advice的目标对象方法
            weave:将advice应用到targetObject上的过程叫织入,spring支持动态织入
            targetObject:advice别调用的对象
            proxy:spring默认使用jdk的动态代理,代理是运行时创建的,也可以是cgLib代理

原创粉丝点击