SpringAOP 之静态代理

本贴最后更新于 1905 天前,其中的信息可能已经物是人非

一、SpringAOP

8f71f78b849f4464a5e73093203e0807.png

⒈ AOP

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

⒉ 目的

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

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

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

二、静态代理

  1. 需要知道核心类(被代理类)是哪一个类,并且有什么方法。

  2. 非核心的代码需要重复写多次,显得代码的结构臃肿,形成代码冗余。

  3. 非核心类(代理类)需要实现核心类(被代理类)实现的接口,也就是他们需要实现共同的接口,但是以核心类实现的接口(被代理类)为准。

三、动态代理

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

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

四、静态代理示例

1. 业务介绍

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

2. 具体代码

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

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

 package com.basic.tu.proxy.myStatic;

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

	public void studyAtHome(String core);

	public void studyAtSchool(String core);

}

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

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

import com.basic.tu.proxy.myStatic.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) 创建一个高三学生的代理类:G3StudentProxy,并且实现了高三学生接口(G3Student)

package com.basic.tu.proxy.myStatic.proxy;

import com.basic.tu.proxy.myStatic.G3Student;
import com.basic.tu.proxy.myStatic.impl.G3Student_boy;
import com.basic.tu.proxy.myStatic.impl.G3Student_girl;

/*
*    代理对象(G3StudentProxy)的目的是帮助核心对象(G3Student_boy)做非核心的事情。
*    但是代理对象(G3StudentProxy)必须和核心对象(G3Student_boy)实现共同的 G3Student 接口。
*/
public class G3StudentProxy implements G3Student {

	//定义一个高三学生接口 作为属性,目的是就是在处理完代理需要做的事情之后调用高三男孩或者是高三女孩需要做的核心业务,
	//但是不是代理具体去做这些核心的事情,只是调用它们而已。    
	private G3Student g3S;

	//创建一个代理的参数为 高三学生接口 的构造函数,判断但传入的字符串为boy就构造一个高三男孩的实例,如果传入的参数为girl就构造一个高三女孩的实例。
	public G3StudentProxy(String sex) {
		if ("boy".equals(sex)) {
			g3S = new G3Student_boy();
		} else if ("girl".equals(sex)) {
			g3S = new G3Student_girl();
		}
	}

	@Override
	public void studyAtHome(String core) {
		//这个是代理(G3StudentProxy)准备饭菜的需要做的流程:    
		System.out.println("代理:准备买菜");
		System.out.println("代理:准备洗菜");
		System.out.println("代理:准备炒菜");
		System.out.println("代理:准备煮饭");
		System.out.println("-----------------");

		//通过定义的属性,并且在调用G3Student_proxy的含参数的构造函数创建相对应的实例,调用这个具体的实例的方法
		g3S.studyAtHome(core);

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

	@Override
	public void studyAtSchool(String core) {
		//这个是代理准备(G3StudentProxy)饭菜的需要做的流程:    
		System.out.println("代理:准备买菜");
		System.out.println("代理:准备洗菜");
		System.out.println("代理:准备炒菜");
		System.out.println("代理:准备煮饭");
		System.out.println("-----------------");

		//通过定义的属性,并且在调用G3Student_proxy的含参数的构造函数创建相对应的实例,调用这个具体的实例的方法
		g3S.studyAtSchool(core);

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

}

(4) 测试

package com.basic.tu.proxy.myStatic;

import com.basic.tu.proxy.myStatic.proxy.G3StudentProxy;

public class Test {

	public static void main(String[] args) {
		//创建一个代理对象,并且传入相对应的参数构造出具体的实例
		G3Student b = new G3StudentProxy("boy");
		//通过这个代理对象执行相关的方法(代理对象和核心对象有共同接口)
		b.studyAtHome("小明");
		b.studyAtSchool("小明");
	}

}

(5) 结果

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

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

五、小结

由上面的例子我们可以简单模拟一个静态代理的实例,但是我们发现,这个代理做的事情会因为核心对象业务多而变得多起来,而且这些代理做的事情都是相同的没有变化的:

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

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

并且,如果我们要修改这些流程中的某一个流程的时候会发现要改多处,而且都是相同的代码,所以这个时候使用动态代理就可以轻松解决这个问题。

转载自:http://www.cnblogs.com/demoMeng/p/5880909.html
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    940 引用 • 1458 回帖 • 159 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3167 引用 • 8207 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    :joy: :joy:

  • KevinBlandy

    咋呼一看,静态代理。好新奇的词儿,进来一看。。。。。。这个不是传说中的装饰者模式??