1.代理模式。

2.静态代理原理及实践。

3.动态代理原理及实践。

4.Spring AOP原理及实战。

静态代理原理及实践

package test.staticProxy;
// 接口
public interface IUserDao {
void save();
void find();
}
//目标对象
class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("模拟:保存用户!");
}
@Override
public void find() {
System.out.println("模拟:查询用户");
}
}
/**
静态代理
特点:
1. 目标对象必须要实现接口
2. 代理对象,要实现与目标对象一样的接口
*/
class UserDaoProxy implements IUserDao{
// 代理对象,需要维护一个目标对象
private IUserDao target = new UserDao();
@Override
public void save() {
System.out.println("代理操作: 开启事务...");
target.save(); // 执行目标对象的方法
System.out.println("代理操作:提交事务...");
}
@Override
public void find() {
target.find();
}
}

静态代理的缺点:

代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理

如果增加一个方法,除了实现类需要实现这个方法外,所有的代理类也要实现此方法,增加了代码的 维护成本,使用动态代理可以解决

动态代理原理及实践

package com.tanlei.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author <a href="mailto:lei.tan@vtradex.net">谭磊</a>
* @since 2019-01-02 17:16
*/ //动态代理: 代理工厂,给多个目标对象生成代理对象
public class ProxyFactory {
//接收一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
} //返回目标对象(target)代理后的对象(Proxy)
public Object getProxyInstance(){
Object proxy= Proxy.newProxyInstance(
target.getClass().getClassLoader(),//目标对象使用的 类加载器
target.getClass().getInterfaces(), //目标对象实现的 所有接口
new InvocationHandler() { //执行代理对象方法时触发
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取当前执行的方法的方法名
String methodName=method.getName();
//方法返回值
Object result=null;
if("find".equals(methodName)){
//直接调用目标对象方法
result=method.invoke(target, args);
}else{
System.out.println("开启事务...");
//执行目标对象方法
result=method.invoke(target, args);
System.out.println("提交事务...");
}
return result;
}
}
);
return proxy;
} }
package com.tanlei.test;

/**
* @author <a href="mailto:lei.tan@vtradex.net">谭磊</a>
* @since 2019-01-02 17:04
*/
public class Main {
public static void main(String[] args) {
//创建目标对象
IUserDao target=new UserDao();
System.out.println("目标对象: "+target.getClass()); //代理对象
IUserDao proxy= (IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println("代理对象: "+proxy.getClass()); //执行代理对象的方法
proxy.save(); }
}

缺点:

使用jdk生成的动态代理的前提是目标类必须有实现的接口。但这里又引入一个问题,如果某个类没有实现接口,就不能使用JDK动态代理,所以Cglib代理就是解决这个问题的。

spring AOP原理及实战

AOP的定义:面向切面编程,核心原理是使用动态代理模式在方法执行前后或出现异常时加入相关逻辑。

通过定义和前面代码我们可以发现3点:

1.AOP是基于动态代理模式。

2.AOP是方法级别的(要测试的方法不能为static修饰,因为接口中不能存在静态方法,编译就会报错)。

3.AOP可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。

Spring是如何生成代理对象的?:

1.创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。

2.如果目标对象有实现接口,使用jdk代理。如果目标对象没有实现接口,则使用Cglib代理。然后从容器获取代理后的对象,在运行期植入"切面"类的方法。通过查看Spring源码,我们在DefaultAopProxyFactory类中,找到这样一段话。

知道了原理,现在我们将自己手动实现Spring的AOP:

package test.spring_aop_anno;

import org.aspectj.lang.ProceedingJoinPoint;

public interface IUserDao {
void save();
}
//用于测试Cglib动态代理
class OrderDao {
public void save() {
//int i =1/0;用于测试异常通知
System.out.println("保存订单...");
}
}
//用于测试jdk动态代理
class UserDao implements IUserDao {
public void save() {
//int i =1/0;用于测试异常通知
System.out.println("保存用户...");
}
}
//切面类
class TransactionAop {
public void beginTransaction() {
System.out.println("[前置通知] 开启事务..");
}
public void commit() {
System.out.println("[后置通知] 提交事务..");
}
public void afterReturing(){
System.out.println("[返回后通知]");
}
public void afterThrowing(){
System.out.println("[异常通知]");
}
public void arroud(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("[环绕前:]");
pjp.proceed(); // 执行目标方法
System.out.println("[环绕后:]");
}
}

Spring的xml配置文件

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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userDao" class="test.spring_aop_anno.UserDao">bean> <bean id="orderDao" class="test.spring_aop_anno.OrderDao">bean> <bean id="transactionAop" class="test.spring_aop_anno.TransactionAop">bean> <aop:config> <aop:pointcut expression="execution(* test.spring_aop_anno.*Dao.*(..))" id="transactionPointcut"/> <aop:aspect ref="transactionAop"> <aop:around method="arroud" pointcut-ref="transactionPointcut"/> <aop:before method="beginTransaction" pointcut-ref="transactionPointcut" /> <aop:after method="commit" pointcut-ref="transactionPointcut"/> <aop:after-returning method="afterReturing" pointcut-ref="transactionPointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="transactionPointcut"/>
aop:aspect>
aop:config>
beans>
package com.tanlei.Aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author <a href="mailto:lei.tan@vtradex.net">谭磊</a>
* @since 2019-01-03 16:32
*/
public class Main {
private ApplicationContext context=new ClassPathXmlApplicationContext("applicationcontext_xml.xml"); @Test
public void testProxy(){
//SpringIOC容器中获取对象,测试spring中jdk动态代理方式
IUserDao userDao= (IUserDao) context.getBean("userDao");
System.out.println(userDao.getClass());
userDao.save();
} @Test
public void testCglib(){
// SpringIOC容器中获取对象,测试spring中Cglib动态代理方式
OrderDao orderDao= (OrderDao) context.getBean("orderDao");
System.out.println(orderDao.getClass());
orderDao.save();
} }

到这里,我们已经全部介绍完Spring AOP,回到开篇的问题,我们拿它做什么?

1.Spring声明式事务管理配置。

2.Controller层的参数校验。

3.使用Spring AOP实现MySQL数据库读写分离案例分析

4.在执行方法前,判断是否具有权限。

5.对部分函数的调用进行日志记录。监控部分重要函数,若抛出指定的异常,可以以短信或邮件方式通知相关人员。

6.信息过滤,页面转发等等功能,

Spring_代理的更多相关文章

  1. Spring_总结_04_高级配置(四)_bean的作用域

    一.前言 本文承接上一节:Spring_总结_04_高级配置(三)之处理歧义 1.单例bean Spring应用上下文中所有的bean默认都是单例的.也就是说,不管一个bean被注入到其他bean多少 ...

  2. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  3. nginx配置反向代理或跳转出现400问题处理记录

    午休完上班后,同事说测试站点访问接口出现400 Bad Request  Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...

  4. Visual Studio Code 代理设置

    Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...

  5. DynamicObject - 代理对象的种类

    开箱即用,DynamicProxy提供了多种代理对象,主要分成两个大类: 基于继承(Inheritance-based) 基于继承的代理是通过继承一个代理类来实现,代理拦截对类的虚(virtual)成 ...

  6. SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论

    异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...

  7. 实现代理设置proxy

    用户在哪些情况下是需要设置网络代理呢? 1. 内网上不了外网,需要连接能上外网的内网电脑做代理,就能上外网:多个电脑共享上外网,就要用代理: 2.有些网页被封,通过国外的代理就能看到这被封的网站:3. ...

  8. 23种设计模式--代理模式-Proxy

    一.代理模式的介绍       代理模式我们脑袋里出现第一个词语就是代购,其实就是这样通过一个中间层这个中间成是属于什么都干什么都买得,俗称"百晓生",在平时得开发中我们经常会听到 ...

  9. 使用Java原生代理实现AOP

    ### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...

随机推荐

  1. Python学习day11-函数基础(1)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  2. Python学习day05 - Python基础(3) 格式化输出和基本运算符

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  3. ckeditor图片上传二三事

    最近实验室要用ckeditor,踩了几个小坑记录下. 1.出现iframe跨域问题 response.setHeader("X-Frame-Options", "SAME ...

  4. 第一个入驻阿里云自营心选商城,如今它已经是营收过亿的SaaS独角兽

    淘宝心选.网易严选.小米有品...越来越多的企业电商自有品牌围绕“低价好物”大做文章,用创新赢得了市场.作为To B从业人员,不由思考:C端的成功是否可以复制在B端? 伴随着互联网下半场的到来,云计算 ...

  5. Java 容易疑惑的一些杂记录

    1 final.finally和finalize final 是一个关键字 ,final 修饰 对象不能被修改,final 修饰的方法不能被重写,final 修饰的 类 不能被继承. finally ...

  6. PAT甲级——A1011 World Cup Betting

    With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excite ...

  7. jmeter是什么

    Apache JMeter 是Apache 组织开发的基于 Java 的压力测试工具: 适用的测试领域:地方 用于对软件做压力测试,它可以用于测试静态和动态资源,例如:静态文件,Java 小程序.CG ...

  8. 《数据结构与算法分析——C语言描述》ADT实现(NO.00) : 链表(Linked-List)

    开始学习数据结构,使用的教材是机械工业出版社的<数据结构与算法分析——C语言描述>,计划将书中的ADT用C语言实现一遍,记录于此.下面是第一个最简单的结构——链表. 链表(Linked-L ...

  9. Newtonsoft.json 二次引用出错解决办法

    一.一般在C# 项目中二次引用会出现如下错误: 解决办法:用编辑器打开项目下的文件(*.csproj),可以找到在这个文件中,Newtonsoft.Json的引用,删掉引用,然后在项目中重新引用就可以 ...

  10. 2019-3-8-win10-uwp-一张图说明水平对齐和垂直对齐

    title author date CreateTime categories win10 uwp 一张图说明水平对齐和垂直对齐 lindexi 2019-03-08 10:45:40 +0800 2 ...