JAVA代理模式学习Demo

1,普通代理模式

目标接口

package com.amaker.proxy;

public interface TargetInterface {
	public void queryPerson();
}

目标实现类

package com.amaker.proxy;

public class TargetImpl implements TargetInterface{

	@Override
	public void queryPerson() {
		
		System.out.println("查询学生中................");
		
	}

}

代理实现类:

package com.amaker.proxy;

public class TargetProxy implements TargetInterface{
	
	
	private TargetInterface target;
	
	public TargetProxy(TargetInterface target){
		this.target = target;
	}
	
	@Override
	public void queryPerson() {
		this.target.queryPerson();
	}

}

测试类:

package com.amaker.proxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		TargetInterface target = new TargetImpl();
		TargetInterface proxy = new TargetProxy(target);
		proxy.queryPerson();
	}

}


2,动态代理:jdkproxy     这里以保存、删除、查询学生为例,使用事物。

Person

package com.amaker.proxy.jdkproxy;

public class Person {
	
}

PersonDao

package com.amaker.proxy.jdkproxy;

public interface PersonDao {
	public void savePerson();
	public void deletePerson();
	public void queryPerson();
}

PersonDaoImpl

package com.amaker.proxy.jdkproxy;

public class PersonDaoImpl implements PersonDao{

	@Override
	public void deletePerson() {
		System.out.println("delete person");
		
	}

	@Override
	public void queryPerson() {
		System.out.println("query person");
		
	}

	@Override
	public void savePerson() {
		System.out.println("save person");
		
	}

}


TransAction 模拟事物处理类

package com.amaker.proxy.jdkproxy;

public class TransAction {
	public void startAction() {
		System.out.println("开启事务");
	}

	public void stopAction() {
		System.out.println("结束事务");
	}
}

代理类PersonInterceptor

package com.amaker.proxy.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PersonInterceptor implements InvocationHandler{
	private PersonDao personDao;
	private TransAction transAction;
	
	public PersonInterceptor(PersonDao personDao,TransAction transAction){
		this.personDao = personDao;
		this.transAction = transAction;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		if(method.getName().startsWith("save") || method.getName().startsWith("delete") ){
			this.transAction.startAction();
			method.invoke(this.personDao, args);
			this.transAction.stopAction();
		}else{
			method.invoke(this.personDao, args);
		}
		
		
		return null;
	}

}

测试类:

package com.amaker.proxy.jdkproxy;

import java.lang.reflect.Proxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		
		PersonDao dao = new PersonDaoImpl();
		TransAction transAction = new TransAction();
		PersonInterceptor  personInterceptor = new PersonInterceptor(dao,transAction);
		
		
		PersonDao daoProxy = (PersonDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), personInterceptor);
		daoProxy.savePerson();
		daoProxy.deletePerson();
		daoProxy.queryPerson();
	}

}




3,动态代理:cglib

实体类:

package com.amaker.proxy.cglib;

public class Person {
	
}


事物操作类:

package com.amaker.proxy.cglib;

public class TransAction {
	public void startAction() {
		System.out.println("开启事务");
	}

	public void stopAction() {
		System.out.println("结束事务");
	}
}


目标类:

package com.amaker.proxy.cglib;

public class PersonDaoImpl{

	public void deletePerson() {
		System.out.println("delete person");
		
	}

	public void queryPerson() {
		System.out.println("query person");
		
	}

	public void savePerson() {
		System.out.println("save person");
		
	}

}


代理类:

package com.amaker.proxy.cglib;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class PersonInterceptor implements MethodInterceptor{
	private PersonDaoImpl personDao;
	private TransAction transAction;
	
	public PersonInterceptor(PersonDaoImpl personDao,TransAction transAction){
		this.personDao = personDao;
		this.transAction = transAction;
	}
	
	/**
	 * 产生代理对象
	 * 
	 * 代理类与目标类是继承关系
	 * 
	 * 
	 * 代理类是目标类的子类
	 * @return
	 */
	public Object createProxy(){
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.personDao.getClass()); //给代理类设置一个父类
		enhancer.setCallback(this); //设置回调函数(拦截器)
		return enhancer.create();
	}
	

	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		if(arg1.getName().startsWith("save") || arg1.getName().startsWith("delete") ){
			this.transAction.startAction();
			arg1.invoke(this.personDao, arg2);
			this.transAction.stopAction();
		}else{
			arg1.invoke(this.personDao, arg2);
		}
		return null;
	}


}


测试类:

package com.amaker.proxy.cglib;

import java.lang.reflect.Proxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		PersonDaoImpl personDaoImpl = new PersonDaoImpl();
		TransAction transAction = new TransAction();
		PersonInterceptor personInterceptor =  new PersonInterceptor(personDaoImpl,transAction);
		PersonDaoImpl proxy = (PersonDaoImpl) personInterceptor.createProxy();
		proxy.savePerson();
		proxy.deletePerson();
		proxy.queryPerson();
	}
}


总结:

一般的代理模式的组成:

    1、目标接口


    2、目标类



    3、代理类
    
    
    
动态代理模式:

    1、jdk动态代理
    
        1、组成:
        
            1、目标接口
            
            2、目标类
            
            3、代理类
            
            4、拦截器
            
            
        2、目标对象和代理对象实现了共同的接口
        
        
        3、优点和缺点:
        
            优点:把数据库的操作和事务的操作分离
            
                    在客户端是面向接口编程
            
            缺点:写一个目标类就得写一个接口
    
        
    
    2、CGLIB的动态代理
    
        1、导入cglib包
        
        2、组成:
        
            1、目标类
            
            2、拦截器
            
            
            3、代理类
            
        在CGLIB动态代理中,生成的代理对象和目标对象是继承关系   目标类是父类
        
        
        3、优点和缺点:
        
                优点:
                        没有接口,比较简单
                        
                        应用:hibernate   session.load方法
                        
                缺点:
                
                        在进行业务逻辑编程的时候,在客户端希望是面向接口编程。
                        
                        
                        
    效率:CGLIB稍微高点




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值