Java代理模式

23中(Gof)中代理模式中的一种,AOP本身就是基于动态代理实现的,所以掌握了代理模式对AOP的学习很有帮助,所以先讲下代理模式

1.静态代理模式

如果代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理,这种情况下的代理类通常都是我们在java代码中定义的。通常情况下,静态代理中的代理类和目标类会实现同一接口或是派生自相同的父类。

1.1创建接口

package com.sxt.dao;

public interface IUserDao {
	void run(String msg);

}

1.2创建接口实现类

package com.sxt.dao.impl;

import com.sxt.dao.IUserDao;

public class UserDaoImpl implements IUserDao{

	@Override
	public void run(String msg) {

		System.out.println("周杰伦:"+msg);
	}

}

1.3创建静态代理模式

package com.sxt.proxy;

import com.sxt.dao.IUserDao;
import com.sxt.dao.impl.UserDaoImpl;

public class ProxyStatice implements IUserDao{

	public IUserDao user;

	public ProxyStatice(IUserDao user) {
		super();
		this.user = user;
	}

	@Override
	public void run(String msg) {
		System.out.println("--目标对象执行之前--");
		// 目标对象增强
		msg = msg.toUpperCase();
		// 执行目标对象的方法
		user.run(msg);

		System.out.println("--目标对象执行之后--");

	}



}

1.4测试实现

\package com.sxt;




import com.sxt.dao.IUserDao;
import com.sxt.dao.impl.UserDaoImpl;
import com.sxt.proxy.ProxyStatice;

public class Test {
	public static void main(String[] args) {
		// 1.获取目标对象
		IUserDao user = new UserDaoImpl();
		// 2.获取代理类增强目标类
		ProxyStatice x =new ProxyStatice(user);
		// 3.执行业务
		x.run("hello");
	}
}

2.动态代理模式

代理类在程序运行时创建的代理方式被称为 动态代理。 也就是说,在这种情况下,代理类并不是在java代码中定义的,而是在运行时根据我们在java代码中的"指示"动态生成的。

|代理类型|使用场景 ||--|--|| JDK动态代理 |如果目标对象实现了接口,采用JDK的动态代理 || cglib动态代理 |如果目标对象没有实现接口,必须采用cglib动态代理 |

2.1JDK动态代理

声明接口

package com.sxt.dao;

public interface IUserDao {
	void run(String msg);

}

创建实现类

package com.sxt.dao.impl;

import com.sxt.dao.IUserDao;

public class UserDaoImpl implements IUserDao{

	@Override
	public void run(String msg) {

		System.out.println("周杰伦:"+msg);
	}

}

JDK动态代理shixian

package com.sxt;




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

import com.sxt.dao.IUserDao;
import com.sxt.dao.impl.UserDaoImpl;


public class Test {
	public static void main(String[] args) {
		// 1.获取目标对象
		IUserDao user = new UserDaoImpl();
		// 2.获取代理类增强目标类
		IUserDao object = (IUserDao) Proxy.newProxyInstance(user.getClass().getClassLoader()//实现类加载器
				, user.getClass().getInterfaces()//实现类的所有接口
				, new InvocationHandler() {//处理器

					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("处理前");
						String msg =args[0].toString().toUpperCase();
						method.invoke(user, msg);
						System.out.println("处理后");
						return null;
					}
				}
				);
		object.run("hello");
	}
}

测试实现

2.2CGLIB动态代理

导入cglibjar包

创建目标类

package com.sxt.dao.impl;


public class UserDaoImpl{

	public void run(String msg) {

		System.out.println("周杰伦:"+msg);
	}

}

创建cglib工厂

package com.sxt.cglib;

import java.lang.reflect.Method;




import com.sxt.dao.impl.UserDaoImpl;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * cglib代理类
 * @author Administrator
 *
 */
public class Cglib implements MethodInterceptor{

	private UserDaoImpl user;

	public Cglib(UserDaoImpl user) {
		super();
		this.user = user;
	}
	public UserDaoImpl newProxy(){
		//1.创建Enhancerd对象
		Enhancer e = new Enhancer();
		//2.指定父类方法
		e.setSuperclass(UserDaoImpl.class);
		//3.设置回调方法
		e.setCallback(this);
		return (UserDaoImpl) e.create();
	}

	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		System.out.println("--cglib 执行之前-");
		String msg = arg2[0].toString().toUpperCase();
		arg1.invoke(user, msg);//执行目标对象的方法
		System.out.println("--cglib 执行之后-");
		return null;
	}

}

测试

package com.sxt;




import com.sxt.cglib.Cglib;
import com.sxt.dao.impl.UserDaoImpl;


public class Test {
	public static void main(String[] args) {
		// 1.获取目标对象
		UserDaoImpl user = new UserDaoImpl();
		// 2.获取代理类增强目标类
		UserDaoImpl proxy = new Cglib(user).newProxy();
		proxy.run("hello");
	}
}

04-18 19:24