一、代理的基本简介

首先,在什么时候使用代理:

在面向方面编程过程中,当需要对所有类进行某种操作(如,安全性检查,记录操作日志)时,考虑到OCP原则,我们不能在所有实现类中直接添加某些相关方法,这样一旦需求改变将引起很多麻烦和大量修改性的工作。又考虑到我们所要进行的对于所有类的操作与实现类的具体实现存在正交关系(即二者完全不相关,在功能上不存在“相互”依赖关系)。因此提供代理类,对目标类(接口的真正实现类)进行代理,并在代理类中添加相关附加操作。

其次:代理模式的角色:

抽象角色 :声明真实对象和代理对象的共同接口。

代理角色 :代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口 以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作前后,附加其他的操作,相当于对真实对象进行封装 一些额外的服务。 



真实角色 :代理角色所代表的真实对象,是代理最终要引用的对象。

最后:AOP中的代理:

aspect oriented programming 面向切面编程是将一个功能做成一个切面类,要用的时候,动态的置入到目标中的过程。 Spring的代理有两种,分别为动态代理和静态代理。首先看一下关于AOP的相关术语:

1,Cross Cutting Concern:是一种独立服务,它会遍布在系统的处理流程之中

2,Aspect:对横切性关注点的模块化

3,Advice:对横切性关注点的具体实现

4,Pointcut:它定义了Advice应用到哪些JoinPoint上,对Spring来说是方法调用

5,JoinPoint:Advice在应用程序上执行的点或时机,Spring只支持方法的JoinPoint,这个点也可以使属性修改,如:Aspecj可以支持

6,Weave:将Advice应用到Target Object上的过程叫织入,Spring支持的是动态织入

7,Target Object:Advice被应用的对象

8,Proxy:Spring AOP默认使用JDK的动态代理,它的代理是运行时创建,也可以使用CGLIB代理

spring实现的代理是动态代理,但在介绍动态代理之前,先了解一下静态代理。因为动态代理是为了解决静态代理的遗留问题诞生的。

二、实例解析静态代理

一个客户不想或者不能直接引用 或者说在引用目标对象前后要进行一些额外的工作 时候,代理对象可以在客户端和目标对象之间起到中介的作用。比如,给一个方法加日志,判断这个方法是否正确执行结束!

2.1,不用代理

实现类User:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

public class User implements IUser {

	@Override
public void addUser() {
System.out.println("Angel: addUser()");
System.out.println("------------Angel:addUser()_End successful------------------");
} }</span>

测试类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; import junit.framework.TestCase; public class TestUser extends TestCase { public void testAdd() {
// 读取配置文件
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
User user=(User)factory.getBean("user");
user.addUser();
}
}</span>

配置文件略

从上面的例子,可以发现的是,当我们需要记录每个方法的执行记录时,不得不为每个类的每个方法添加System.out.println("------------Angel:addUser()_End successful------------------");这样就加重了实现类的负担,这时候,我们引入一个代理类,让代理去帮助我们实现检测方法是否成功:

2.2,加入代理

加入代理类,让它跟user同时实现一个借口IUser,然后客户端通过代理,去访问user类。

IUser接口:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

public interface IUser {

	public void addUser();

}
</span>

user实现类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

public class User implements IUser {

	@Override
public void addUser() {
System.out.println("Angel: addUser()");
}
}</span>

user代理类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

public class UserProxy implements IUser {

	private User user;
public void setUser(User user){
this.user=user;
} @Override
public void addUser() {
user.addUser();
this.isSuccess();
} public void isSuccess(){
System.out.println("------------Angel:addUser()_End successful------------------");
} }
</span>

applicationContext配置文件:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="user" class="com.angel.spring.User"/>
<bean id="userProxy" class="com.angel.spring.UserProxy">
<property name="user" ref="user"/>
</bean> </beans>
</span>

测试类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; import junit.framework.TestCase; public class TestUser extends TestCase { public void testAdd() {
// 读取配置文件
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserProxy userProxy=(UserProxy)factory.getBean("userProxy");
userProxy.addUser();
}
}
</span>

三、总结

在使用了代理类后,我们在实现检验方法是否成功时,就不用去修改我们的具体实现类,而是通过中介代理去是实现,从而也就满足了开闭原则。但是,如果有100个实现类,甚至更多呢?如果我们仍坚持采用静态代理的方法,那么,我们必将为这100个实现类,甚至更多建立代理类。显然,这也是一个麻烦,怎样解决呢?下一篇博客,将介绍AOP的代理实现方式:动态代理!

【spring 3】AOP:静态代理的更多相关文章

  1. AOP静态代理解析1-标签解析

    AOP静态代理使用示例见Spring的LoadTimeWeaver(代码织入) Instrumentation使用示例见java.lang.instrument使用 AOP的静态代理主要是在虚拟机启动 ...

  2. Spring专题1: 静态代理和动态代理

    合集目录 Spring专题1: 静态代理和动态代理 为什么需要代理模式? 代理对象处于访问者和被访问者之间,可以隔离这两者之间的直接交互,访问者与代理对象打交道就好像在跟被访者者打交道一样,因为代理者 ...

  3. spring学习三:Spring的Aop、代理

    ref:https://mp.weixin.qq.com/s/J77asUvw8FcnF-6YlX6AAw AOP相关术语:    Joinpoint(连接点):类里面可以被增强的方法,这些方法称为连 ...

  4. spring——AOP(静态代理、动态代理、AOP)

    一.代理模式 代理模式的分类: 静态代理 动态代理 从租房子开始讲起:中介与房东有同一的目标在于租房 1.静态代理 静态代理角色分析: 抽象角色:一般使用接口或者抽象类来实现(这里为租房接口) pub ...

  5. spring(AOP)静态代理

    姓名:黄于霞      班级:软件151 1.定义抽象主题接口,假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: 2.主题类,算术类,实现抽象接口. 3.代理类 4.测试运行 5.总 ...

  6. Spring的AOP与代理

    spring 支持两种注入方式: setter/constructor 支持多种配置方式: xml/java5注解/java类配置 支持两种事务管理: 声明性/编程性 实际上上述方式只有一个就能保证系 ...

  7. 浅谈Spring的AOP实现-代理机制

    说起Spring的AOP(Aspect-Oriented Programming)面向切面编程大家都很熟悉(Spring不是这次博文的重点),但是我先提出几个问题,看看同学们是否了解,如果了解的话可以 ...

  8. Spring ( 四 )Spring的AOP动态代理、切面编程

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.AOP切面编程 1.什么是AOP AOP是面向切面编程.全称:Aspect Oriented Pro ...

  9. 8、Spring教程之静态代理/动态代理

    为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...

  10. AOP静态代理解析2-代码织入

    当我们完成了所有的AspectJ的准备工作后便可以进行织入分析了,首先还是从LoadTimeWeaverAwareProcessor开始. LoadTimeWeaverAwareProcessor实现 ...

随机推荐

  1. (WF)InvalidWorkflowException

    之前一直运行正常的xaml突然不能运行了,总是显示如下错误. The test caught an unhandled exception. Caught: System.Activities.Inv ...

  2. 由csdn开源项目评选中闹出刷票问题想到投票程序的设计

    帖子<#CSDN刷票门# 有没有人在恶意刷票?CSDN请告诉我!用24小时监控数据说话!> http://www.cnblogs.com/sanshi/p/3155946.html 网站投 ...

  3. Servlet细节

    Servlet细节 线程不安全的做法: * 不要在Servlet中创建成员!创建局部变量即可! * 可以创建无状态成员! * 可以创建有状态的成员,但状态必须为只读的!(不提供set方法) 1.Ser ...

  4. PLSQL_Oracle PLSQL处理日期方式大全(概念)

    TO_DATE格式  Day:  dd number 12  dy abbreviated fri  day spelled out friday  ddspth spelled out, ordin ...

  5. python (3)简单语法:字符串(strip函数),数据类型

    一:字符串重复,索引,切片(字符串命令strip) 函数原型strip 声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾处,位于 rm删除序列的 ...

  6. React Native 开发。

    1.react-native run-android 安装 2.react-native start  开启调试端口

  7. STM32的串口

    一:2个状态位_itstatus与_flagstatus的区别: _flagstatus:只是读状态标志,不管中断是否使能或发生.例如使用查询方式发送数据就需要读改状态位. _itstatus:和中断 ...

  8. Airbnb面试的27个奇葩问题,你 hold 住吗?

    Airbnb 目前估值 255 亿美金,排名世界科技公司第三.但如果你想去他家工作,可能首先需要回答一些很棘手的问题. 以下,是 BI 通过 Glassdoor 信息收集到的:曾经历 Airbnb 面 ...

  9. [Other] 自定义MIME类型支持FLV的相关设置

    刚测试知道为何服务器无法播放flv的原因,特此记录而已. 网络空间支持FLV的相关设置,就是自定义一个MIME类型,一般虚拟主机管理里面都有这个选项 自定义MIME类型 扩展名: .flv MIME类 ...

  10. [SQJ]sql如何实现类似统计的功能

    假设mssql2000中, 有如下表: table Class class_No course_Name ----------------------------------- chinese mat ...