SpringAOP之动态代理

  |   0 评论   |   671 浏览

一、SpringAOP

8f71f78b849f4464a5e73093203e0807.png

⒈ AOP

Aspect Oriented Programming 面向切面编程, 实现的是核心业务和非核心业务之间的的分离,让核心类只做核心业务,代理类只做非核心业务。

⒉ 目的

  1. 把核心业务和非核心业务进行分离。

  2. 把多个非核心业务处理(点)变成一个切面(之前的非核心业务代码需要写多次变成只需要写一次。

  3. 要求:只有当核心类中有多个业务需要进行处理的时候使用AOP较为合理,如果只有一个业务需要被处理那么就没有必要使用AOP了。

二、动态代理

  1. 不需要知道核心类(被代理类)具体是什么类。

  2. 非核心类(代理类)需要实现InvocationHandler接口。

在原有的静态代理的基础上进一步的完善,由于静态代理中,重复写了相同的代码使得代码的整体结构显得冗余,而且还不同的核心类还需要有不用的代理类,是写死了的具体的类。所以需要使用动态代理来代替静态代理
  

三、动态代理示例

1. 业务介绍

假定高三学生为核心类,学生的家人是代理类。高三学生需要做的核心业务有:在家学习(studyAtHome)、在学校学习(studyAtHome);家人需要做的非核心业务为:准备饭菜(买、洗、炒、煮饭)。准备补品(购买、熬制、加佐料)。

2. 具体代码

github地址:https://github.com/tsgkim/JavaBasic/tree/master/JavaBasic/src/com/basic/tu/proxy/myDynamic

(1) 创建一个高三学生的接口(G3Student)

 package com.basic.tu.proxy.myDynamic;

//首先定义一个接口,用来高三学生来是实现,
//在这个接口中声明一个在家学习和一个在学校学习的方法
public interface G3Student {

	public void studyAtHome(String core);

	public void studyAtSchool(String core);

}

(2) 创建一个高三学生实现类:G3Student_boy,并且这个类实现高三学生接口(G3Student)

package com.basic.tu.proxy.myDynamic.impl;

import com.basic.tu.proxy.myDynamic.G3Student;

//定义一个高三男孩的类(目标对象、核心对象、target对象),实现了高三学生的接口。
public class G3Student_boy implements G3Student {

	//高三男孩 的第一个业务流程:在家学习
	@Override
	public void studyAtHome(String core) {
		//核心的事情在家学习。
		System.out.println(core + "在HOME学习");
	}

	//高三男孩 的第二个业务流程:在学校学习
	@Override
	public void studyAtSchool(String core) {
		//核心的事情在家学习。
		System.out.println(core + "在SCHOOOL学习");
	}

}

(3) 创建一个高三学生的代理类(G3StudentHandler),并且实现了InvocationHandler接口

package com.basic.tu.proxy.myDynamic.handler;

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

public class G3StudentHandler implements InvocationHandler {

	/**
	 * 态代理的代理类中定义了一个以Object类型的属性,而静态代理定义的是具体的G3Student的接口类型的属性。
	 * 所以,动态代理这样定义保证了,这个代理可以带不同的个核心类如:G3Studentboy、G3Studentgirl。
	 */
	private Object g3Stu;

	public G3StudentHandler(Object g3Stu) {
		this.g3Stu = g3Stu;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		////调用代理的在核心对象处理核心业务之前的方法
		before();

		/**
		 * 核心对象的核心方法
		 * 
		 * 自动调用传入的核心类对象(G3Student_boy)的方法,并且传入参数args,返回一个Object类型的值。
		 * 具体是调用什么方法,传入什么参数,都不需要我们具体关注,只需写上这条代码,并且把返回值返回即可。
		 */
		Object returnValue = method.invoke(g3Stu, args);

		//调用代理的在核心对象处理核心业务之后的方法
		after();

		return returnValue;
	}

	private void before() {
		//这个是代理(G3StudentHandler)准备饭菜的需要做的流程:    
		System.out.println("代理:准备买菜");
		System.out.println("代理:准备洗菜");
		System.out.println("代理:准备炒菜");
		System.out.println("代理:准备煮饭");
		System.out.println("-----------------");
	}

	private void after() {
		//这个是代理(G3StudentHandler)准备补品的需要做的流程:
		System.out.println("-----------------");
		System.out.println("代理 :购买补品");
		System.out.println("代理 :熬制部品");
		System.out.println("代理 :加入佐料");
		System.out.println();
	}

}

(4) 测试

package com.basic.tu.proxy.myDynamic;

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

import com.basic.tu.proxy.myDynamic.handler.G3StudentHandler;
import com.basic.tu.proxy.myDynamic.impl.G3Student_boy;

public class Test {

	public static void main(String[] args) {
		G3Student boy = new G3Student_boy();

		InvocationHandler handler1 = new G3StudentHandler(boy);

		G3Student g3boy = (G3Student) Proxy.newProxyInstance(boy.getClass().getClassLoader(),
				boy.getClass().getInterfaces(), handler1);

		g3boy.studyAtSchool("小明");
		g3boy.studyAtHome("小明");
	}

}

(5) 结果

代理:准备买菜
代理:准备洗菜
代理:准备炒菜
代理:准备煮饭
-----------------
小明在SCHOOOL学习
-----------------
代理 :购买补品
代理 :熬制部品
代理 :加入佐料

代理:准备买菜
代理:准备洗菜
代理:准备炒菜
代理:准备煮饭
-----------------
小明在HOME学习
-----------------
代理 :购买补品
代理 :熬制部品
代理 :加入佐料
转载自:http://www.cnblogs.com/demoMeng/p/5881473.html

评论

发表评论

validate