Spring学习(1)AOP初步—JDK动态代理

代理模式主要有两种:静态代理动态代理

代理模式——角色(三种)

         抽象主题角色

         代理主题角色

         真实主题角色

通过代理角色获得真实角色的内容!

实现方法:

         第一种,代理角色和真实角色都实现同一个接口,来实现代理;

         第二种,通过实现继承来实现代理,即代理角色通过继承真实角色来重写父类的方法,从而实现代理;

下面是在用户注册前面添加的一个简单的检测逻辑:

第一种、实现统一接口的代理

RegInterface.java

package com.yw.xu;

public interface RegInterface {
	void register();
}

Register.java 

package com.yw.xu;
/**
* 真实角色
 */
public class Register implements RegInterface{
	
	@Override
	public void register(){
		System.out.println("用户登录");
	}
}

RegisterProxy.java

package com.yw.xu;
/**
 * 代理角色
 */
public class RegisterProxy implements RegInterface{
	Register reg;
	public RegisterProxy(Register reg){
		this.reg = reg;
	}
	@Override
	public void register(){
		System.out.println("用户名检测");
		reg.register();
	}
}

Test.java

package com.yw.xu;
public class Test {
	public static void main(String[] args) {
		RegisterProxy proxy = new RegisterProxy(new Register());
		// RegisterProxy2 proxy = new RegisterProxy2(new Register());
		proxy.register();
	}
}


第二种:使用继承方法代理


Register2.java

package com.yw.xu;
/**
* 真实角色
 */
public class Register2{
	
	public void register(){
		System.out.println("用户登录");
	}
}

RegisterProxy2.java

package com.yw.xu;
/**
* 代理角色
*/
public class RegisterProxy2 extends Register2{

	Register reg;
	
	public RegisterProxy2(Register reg){
		this.reg = reg;
	}
	
	public void register(){
		System.out.println("用户名检测");
		reg.register();
	}
}

Test.java

package com.yw.xu;
public class Test {
	public static void main(String[] args) {
		//RegisterProxy proxy = new RegisterProxy(new Register());
		RegisterProxy2 proxy2 = new RegisterProxy2(new Register());
		proxy2.register();
	}
}

上面的2种方法,就是一个简单的静态代理方法,一个通过接口方式实现,一种通过继承的方式实现!可以看出静态代理类有一个很大的缺点:当接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。


第二种、动态代理

下面是JDK的动态代理

JDK的代理通过接口实现

JDK的动态代理类:ProxyHander.java

package com.yw.xu.jdkproxy;

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

public class ProxyHander implements InvocationHandler{
	
	Object target;
	public ProxyHander(Object target) {
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("用户检测...");
		Object obj = method.invoke(target, args); //②通过反射方法调用目标业务类的业务方法
		return obj;
	}
	
	//创建代理实例
	public Object newProxyInstance(){
		return Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);//理解java类装载过程
	}
}

接口:RegInterface.java

package com.yw.xu;

public interface RegInterface {
	void register();
}

实现接口类,里面可以包含多种方法:Register.java 

package com.yw.xu;
/**
* 真实角色
 */
public class Register implements RegInterface{
	
	@Override
	public void register(){
		System.out.println("用户登录");
	}
}

测试类

Test.java

package com.yw.xu.jdkproxy;

import com.yw.xu.RegInterface;
import com.yw.xu.Register;

public class Test {
	public static void main(String[] args) {
		ProxyHander proxy = new ProxyHander(new Register());
		RegInterface obj = (RegInterface)proxy.newProxyInstance();//obj是代理对象
		obj.register();		
	}
}

DK动态代理是依靠接口的方式来实现的,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。


你可能感兴趣的:(spring,动态代理,AOP,proxy)