AOP简介

  • 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,
  • 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

开发存在的问题

JDK动态代理

JDK动态代理必须依赖接口(必须有接口)

public interface GoodsDao {
public void save();
public void update();
}

接口实现类:

public class GoodsDaoImpl implements GoodsDao {
@Override
public void save() {
System.out.println("保存操作");
} @Override
public void update() {
System.out.println("更新操作");
}
}

JDK动态代理类:

public class GoodsJDKProxy {
public GoodsDao createProxy(GoodsDao goodsDao){
// 增强功能
GoodsDao goodsDaoProxy = (GoodsDao)Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(), goodsDao.getClass().getInterfaces(),
new InvocationHandler() {
// 当调用对象的时候,所有的方法都会来到这里
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())){
System.out.println("权限检验");
GoodsDao goodsDao1 = (GoodsDao)method.invoke(goodsDao, args);
System.out.println("退出");
return goodsDao1;
}
return method.invoke(goodsDao, args);
}
}); return goodsDaoProxy;
}
}

测试:

@Test
public void test() {
GoodsDao goodsDao = new GoodsDaoImpl();
// goodsDao.save(); GoodsJDKProxy goodsJDKProxy = new GoodsJDKProxy();
GoodsDao proxy = goodsJDKProxy.createProxy(goodsDao);
proxy.save();
proxy.update();
}

cglib动态代理

  • Cglig是一个第三方开源代码 生成类库,动态添加类的属性和方法。
  • 在spring的核心包当中已经引入了cglib

  • 采用的是继承方式来产生的代理对象
public class UserDao {
public void save() {
System.out.println("保存操作");
} public void update() {
System.out.println("更新操作");
}
}

cglib动态代理类:

(1)匿名内部类写法:

public class UserDaoCglibProxy {
public UserDao createCglibProxy(UserDao userDao){
// 1.创建核心类
Enhancer enhancer = new Enhancer();
// 2.设置父类 增强为继承方式(自动创建子类继承父类)
enhancer.setSuperclass(userDao.getClass());
// 3.设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())){
System.out.println("权限检验");
UserDao invoke = (UserDao)methodProxy.invokeSuper(o, objects);
System.out.println("退出");
return invoke;
}
return methodProxy.invokeSuper(o, objects);
}
});
// 4.创建代理对象 就是把子类取出来
UserDao obj = (UserDao)enhancer.create();
return obj;
}
}
public class UserDaoCglibProxy {
public UserDao createCglibProxy(UserDao userDao){
// 1.创建核心类
Enhancer enhancer = new Enhancer();
// 2.设置父类 增强为继承方式(自动创建子类继承父类)
enhancer.setSuperclass(userDao.getClass());
// 3.设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())){
System.out.println("权限检验");
UserDao invoke = (UserDao)method.invoke(userDao, objects);
System.out.println("退出");
return invoke;
}
return method.invoke(userDao, objects);
}
});
// 4.创建代理对象 就是把子类取出来
UserDao obj = (UserDao)enhancer.create();
return obj;
}
}

(2)实现 MethodInterceptor 接口:

public class UserDaoCglibProxy implements  MethodInterceptor{
public UserDao createCglibProxy(UserDao userDao){
// 1.创建核心类
Enhancer enhancer = new Enhancer();
// 2.设置父类 增强为继承方式(自动创建子类继承父类)
enhancer.setSuperclass(userDao.getClass());
// 3.设置回调
enhancer.setCallback(this);
// 4.创建代理对象 就是把子类取出来
UserDao obj = (UserDao)enhancer.create();
return obj;
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())){
System.out.println("权限检验");
UserDao invoke = (UserDao)methodProxy.invokeSuper(o, objects);
System.out.println("退出");
return invoke;
}
return methodProxy.invokeSuper(o, objects);
}
}

测试:

public class UserDaoTest {
@Test
public void test(){
UserDao userDao = new UserDao();
UserDaoCglibProxy userDaoCglibProxy = new UserDaoCglibProxy();
UserDao proxy = userDaoCglibProxy.createCglibProxy(userDao);
proxy.save();
proxy.update();
}
}

Spring的AOP简介

  • AOP思想最早是由AOP联盟组织提出的
  • Spring使用这种思想最好的框架
  • AspectJ
    • Spring的AOP有自己的实现方式,但是这种方式非常繁琐
    • AspectJ 是一个AOP的框架
    • Spring放弃了自己传统的方式 ,引入AspectJ作为自身AOP的开发

AOP相关术语

Joinpoint:连接点

可以被拦截到的方法

能够被增强的方法,这些方法就可以称为是连接点

Pointcut:切入点

真正被拦截的方法,真正被增加的方法

Advice:通知

增加的内容,通常都是封装成一个方法, 这个方法我们就称为通知

Introduction:引介

  • 类层面的增加
  • 给原有的类添加一些新的属性方法
  • 在开发中通常都是给方法进行增加

Target:被增加的对象

Weaving:织入

将通知应用到目标对象的过程

Proxy:代理对象

Aspect:切面

多个通知和多个切入点的集合

Spring中AOP使用

1.引入spring基本jar包

2.引入aop开发的相关jar包

3.配置文件中引入aop约束

applicationContext.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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>

4.Spring测试

  • 测试时,每次都需要获取工厂
  • 通过spring-test,就不用每次获取
  • 添加测试依赖包

5.测试

applicationContext.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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="goodsDao" class="com.xzh.spring.demo2.GoodsDaoImpl"/>
</beans>

实现类:

public class GoodsDaoImpl implements GoodsDao {
@Override
public void save() {
System.out.println("保存操作");
} @Override
public void update() {
System.out.println("更新操作");
}
}

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name="goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.save();
}
}

6.编写一个切面类

public class MyAspect {
public void check(){
System.out.println("权限检验");
} public void exit(){
System.out.println("退出");
}
}

7.将切面交给spring

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="goodsDao" class="com.xzh.spring.demo2.GoodsDaoImpl"/>
<bean id="myAspect" class="com.xzh.spring.demo3.MyAspect"/>
</beans>

8.配置AOP完成对目标产生代理

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="goodsDao" class="com.xzh.spring.demo2.GoodsDaoImpl"/>
<bean id="myAspect" class="com.xzh.spring.demo3.MyAspect"/>
<!--配置AOP-->
<aop:config>
<!--切点:给那个方法做增强-->
<aop:pointcut id="savePoint" expression="execution(* com.xzh.spring.demo2.GoodsDaoImpl.save(..))"/>
<!--配置切面:增强的功能是什么-->
<aop:aspect ref="myAspect">
<aop:before method="check" pointcut-ref="savePoint"/>
<aop:after method="exit" pointcut-ref="savePoint"/>
</aop:aspect>
</aop:config>
</beans>

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name="goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.save();
this.goodsDao.update();
}
}

AOP 与 Spring中AOP使用(上)的更多相关文章

  1. 浅谈spring中AOP以及spring中AOP的注解方式

    AOP(Aspect Oriented Programming):AOP的专业术语是"面向切面编程" 什么是面向切面编程,我的理解就是:在不修改源代码的情况下增强功能.好了,下面在 ...

  2. AOP 与 Spring中AOP使用(下)

    AOP通知类型 前置通知 在目标方法执行之前进行操作 UserDao.java public class UserDao { public void add(){ System.out.println ...

  3. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  4. Spring中AOP原理,源码学习笔记

    一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...

  5. 【spring 5】AOP:spring中对于AOP的的实现

    在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...

  6. Spring中AOP简介与切面编程的使用

    Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...

  7. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  8. Spring 中aop切面注解实现

    spring中aop的注解实现方式简单实例   上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...

  9. Spring中AOP相关源码解析

    前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...

随机推荐

  1. 【日语】日语能力考试N2级核心词汇必备—接续词

    日语能力考试N2级核心词汇必备—接续词 顺接 だから 因为......所以......(下文可用命令,意志劝诱等)その結果  其结果(口语,书面语都行,但是比较生硬)したがって  从而,因而(书面语, ...

  2. awk 常用选项及数组的用法和模拟生产环境数据统计

    awk 常用选项总结 在 awk 中使用外部的环境变量 (-v) awk -v num2="$num1" -v var1="$var" 'BEGIN{print ...

  3. 直接插入排序算法(java)

    直接插入排序是将未排序的数据插入至已排好序序列的合适位置. 具体流程如下: 1.首先比较数组的前两个数据,并排序: 2.比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置: 3.比较第四 ...

  4. 第十八篇:简易版web服务器开发

    在上篇有实现了一个静态的web服务器,可以接收web浏览器的请求,随后对请求消息进行解析,获取客户想要文件的文件名,随后根据文件名返回响应消息:那么这篇我们对该web服务器进行改善,通过多任务.非阻塞 ...

  5. 【OF框架】使用OF.WinService项目,添加定时服务,进行创建启动停止删除服务操作

    准备 使用框架搭建完成项目,包含OF.WinService项目. 了解Window Service 和定时服务相关知识. 一.添加一个定时服务 第一步:了解项目结构 第二步:创建一个新的Job 第三步 ...

  6. Visual Studio(Year)编辑器调试在IIS发布的Web程序出现错误的解决

    如下图所示:

  7. 【蜂窝】at+qcfg="band"的计算和使用

    查询附件 Quectel_EC25_LTE_模块产品规格书_V1.6 可知当前的蜂窝模块所对应的band频带是什么? eg.1 EC25-AU 当前选择4G 优先, FDD LTE 可看手册QCFG命 ...

  8. python中赋值和浅拷贝与深拷贝

    初学编程的小伙伴都会对于深浅拷贝的用法有些疑问,今天我们就结合python变量存储的特性从内存的角度来谈一谈赋值和深浅拷贝~~~ 预备知识一——python的变量及其存储 在详细的了解python中赋 ...

  9. Eclipse修改项目jdk版本

    修改项目jdk版本(@Override的解决方法) (1)Eclipse的Window-Preferences->Java->Compiler(2)Eclipse的Project-> ...

  10. G1混合式GC与三色标记算法详解【纯理论】

    继续基于上一次https://www.cnblogs.com/webor2006/p/11146273.html的理论进一步了解G1. G1收集概览: G1算法将堆划分为若干个区域(Region),它 ...