一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP、代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及BeanNameAutoProxyCreator代理、Aspectj的注解和xml配置文件。

1.代理工厂bean(ProxyFacteryBean)的方式

1.1 接口(Interface)

 package cn.happy.interfaces;

 public interface Advice {

     public void fristMethod();

     public String secondMethod();
}

1.2  接口的实现类

 package cn.happy.impl;

 import cn.happy.interfaces.Advice;

 public class AdviceImpl implements Advice {

     public void fristMethod() {
System.out.println("==fristMethod==");
} public String secondMethod() {
System.out.println("==secondMethod==");
return "abc";
} }

1.3 各种通知增强

1.3.1 前置增强

 package cn.happy.advice;

 import java.lang.reflect.Method;

 public class MethodBeforeAdvice implements
org.springframework.aop.MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("==Before=="); } }

1.3.2  后置增强

 package cn.happy.advice;

 import java.lang.reflect.Method;

 import org.springframework.aop.AfterReturningAdvice;

 public class AfterReturningAdvie implements AfterReturningAdvice {

     public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
System.out.println("==After=="); } }

1.3.3  环绕增强

package cn.happy.aroundadvice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class MyInterceptor implements MethodInterceptor{ public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("==before==");
String result= (String)invocation.proceed();
System.out.println("==after==");
return result;
}
}

1.3.4 异常增强

package cn.happy.exception;

import org.springframework.aop.ThrowsAdvice;

public class MyException implements ThrowsAdvice {
public void afterThrowing(Exception ex){
System.out.println("异常通知");
}
}

1.4 配置文件

<?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"
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"> <!-- 实现类的引入 -->
<bean id="adviceimpl" class="cn.happy.impl.AdviceImpl"></bean>
<!-- 前置增强 通知-->
<bean id="advicebefore" class="cn.happy.advice.MethodBeforeAdvice"></bean>
<!-- 后置增强 通知-->
<bean id="adviceafter" class="cn.happy.advice.AfterReturningAdvie"></bean> <!-- 环绕增强 -->
<bean id="around" class="cn.happy.aroundadvice.MyInterceptor"></bean> <!-- 关联 代理工厂bean ProxyFacteryBean 通知 -->
<!--<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetName" value="adviceimpl"></property>
<property name="interceptorNames" value="advicebefore,adviceafter"></property> </bean>--> <!-- 环绕增强 代理工厂 顾问包装通知 -->
<bean id="aroundserviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="adviceimpl"></property>
<property name="interceptorNames" value="beforeadvisor"></property> </bean> <!-- 切面 通知 -->
<bean id="beforeadvice" class="cn.happy.mymethodbefore.MyMethodBeforeAdvice"></bean> <!-- 顾问 包装advice -->
<bean id="beforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="beforeadvice"></property>
<property name="mappedNames" value="fristMethod,secondMethod"></property>
</bean> <!-- 顾问 包装advice 正则表达式-->
<!--<bean id="beforeadvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="beforeadvice"></property>
<property name="pattern" value=".*Method.*"></property>
</bean>--> <!-- 默认自动代理 默认只找通知-->
<!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>--> <!-- beanname自动代理 可以选择顾问或者通知-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="adviceimpl"></property>
<property name="interceptorNames" value="beforeadvisor"></property>
</bean> </beans>

1.5 测试类

package cn.happy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.interfaces.Advice; public class Test {
/**
* 通知的前置和后置测试
*/
public static void main(String[] args) {
//解析配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
Advice advice= (Advice)ctx.getBean("adviceimpl"); //自动代理beanname的方式
advice.fristMethod();
advice.secondMethod();
}
}

2. 最原始的经典AOP

2.1 最基本分层模式dao、biz、service以及最后测试Test

2.1.1DAO层

package cn.happy.dao;

import cn.happy.entity.User;

   //接口
public interface UDao { //保存方法
public void save(User user);
} //实现类
package cn.happy.dao; import cn.happy.entity.User; public class UserDaoImpl implements UDao{ public void save(User user) {
System.out.println("保存成功");
} }

2.1.2 BIZ层

package cn.happy.biz;

import cn.happy.entity.User;

  //业务接口
public interface UBiz { //保存方法
public void save2(User user);
} //业务实现类
package cn.happy.biz; import cn.happy.dao.UDao;
import cn.happy.entity.User; public class UserBiz implements UBiz{ //dao的对象
private UDao udao;
public void save2(User user) {
udao.save(user); }
public UDao getUdao() {
return udao;
}
public void setUdao(UDao udao) {
this.udao = udao;
} }

2.1.3  AOP模块即service层

package cn.happy.logger;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

  //前置内容
public class LoggerBefore implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("save前置内容");
}
} //后置内容
package cn.happy.logger;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice; public class LoggerAfter implements AfterReturningAdvice{ public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
System.out.println("save后置内容");
}
}

2.1.4 经典的配置文件

<?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-4.1.xsd">
<!-- 业务biz与dao接口对象的实现 -->
<bean id="dao" class="cn.happy.dao.UserDaoImpl"></bean>
<bean id="biz" class="cn.happy.biz.UserBiz">
<property name="udao" ref="dao"></property>
</bean>
<!-- 前置与后置内容的配置 -->
<bean id="before" class="cn.happy.logger.LoggerBefore"></bean>
<bean id="after" class="cn.happy.logger.LoggerAfter"></bean>
<!-- aop的配置 -->
<aop:config>
<aop:pointcut expression="execution(public void save2(cn.happy.entity.User))" id="pointcut"/>
<!-- 在切入点处插入增强处理、完成"织入" -->
<aop:advisor advice-ref="before" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="after" pointcut-ref="pointcut"/>
</aop:config>
</beans>

2.1.5  测试类

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.biz.UBiz;
import cn.happy.entity.User; public class AOPTest { public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UBiz ubiz=(UBiz)context.getBean("biz");
User user=new User();
ubiz.save2(user);
System.out.println("save~ok");
}
}

3. 然后就是Aspectj的注解以及xml配置文件的两种方式了。

3.1 Aspectj注解

3.1.1 接口和实现类

package cn.happy.impl;
//接口
public interface AspectDao { public void add();
public void delete();
} //实现类
package cn.happy.impl; public class AspectjIpml implements AspectDao{
//添加
public void add() {
System.out.println("==ADD==");
}
//删除
public void delete() {
System.out.println("==DELETE==");
}
}

3.1.2 注解类Aspect

package cn.happy.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Before; @org.aspectj.lang.annotation.Aspect
public class Aspect {
//前置增强
@Before(value="execution(public * *(..))")
public void asBefore(){
System.out.println("这是前置增强");
}
//后置增强
@AfterReturning(value="execution(public * *(..))")
public void asAfterReturning(){
System.out.println("这是后置增强");
}
//环绕增强
@Around(value="execution(public * *(..))")
public void asAround(ProceedingJoinPoint pj){
System.out.println("这是环绕前置增强");
try {
pj.proceed();
} catch (Throwable e) {
//抓捕异常
e.printStackTrace();
}
System.out.println("这是环绕后置增强");
}
//异常增强
@AfterThrowing(value="execution(public * *(..))")
public void asThorws(){
System.out.println("这是异常增强");
}
//最终增强
@After(value="execution(public * *(..))")
public void asAfter(){
System.out.println("这是最终增强");
}
}

3.1.3  注解的配置文件

<?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="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
<!-- 增强类 -->
<bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
<!-- 扫描整个项目 关联注解类和实现类 -->
<aop:aspectj-autoproxy /> </beans>

3.1.4   测试类

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.impl.AspectDao; public class AspectjTest {
/**
* 注解测试 */
public static void main(String[] args) {
// 解析配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
AspectDao aspect = (AspectDao) ctx.getBean("aspectimpl");
aspect.add();
aspect.delete();
}
}

4. Aspectj的XML配置法,其他的基本都一样只要修改Aspectj增强类和配置文件就行了

4.1 Aspect增强类只需将那些注解消去即可

package cn.happy.aspectj;
import org.aspectj.lang.ProceedingJoinPoint; public class Aspect {
//前置增强
public void asBefore(){
System.out.println("这是前置增强");
}
//后置增强
public void asAfterReturning(){ System.out.println("这是后置增强");
}
//环绕增强
public void asAround(ProceedingJoinPoint pj){
System.out.println("这是环绕前置增强");
try {
pj.proceed();
} catch (Throwable e) {
//抓捕异常
e.printStackTrace();
}
System.out.println("这是环绕后置增强");
}
//异常增强
public void asThorws(){ System.out.println("这是异常增强");
}
//最终增强
public void asAfter(){ System.out.println("这是最终增强");
}
}

4.2 XML的配置文件会稍微会复杂一点,但大致的还是跟对原始的经典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: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="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
<!-- 增强类 -->
<bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
<!-- Aspectj的XML配置文件 -->
<aop:config>
<aop:pointcut expression="execution(public * *(..))" id="pointcut"/>
<aop:aspect ref="aspectj">
<aop:before method="asBefore" pointcut-ref="pointcut"/>
<aop:after-returning method="asAfterReturning" pointcut-ref="pointcut"/>
<aop:after-returning method="asAround(org.aspectj.lang.ProceedingJoinPoint)" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>

好了,这就是AOP(面向切面编程)的四种实现方式了。希望你们看了之后能让你们对AOP面向切面编程思想有更深的了解。

AOP面向切面编程的四种实现的更多相关文章

  1. 阶段3 2.Spring_08.面向切面编程 AOP_6 四种常用通知类型

    新建项目 复制上节课的pom.xml内的代码 复制java下的代码 测试类也复制过来 配置文件也拷贝过来 logge下增加几个方法 测试方法只需要一个saveAccount方法就可以了 增加其他三种通 ...

  2. 【原创】Android AOP面向切面编程AspectJ

    一.背景: 在项目开发中,对 App 客户端重构后,发现用于统计用户行为的友盟统计代码和用户行为日志记录代码分散在各业务模块中,比如在视频模块,要想实现对用户对监控点的实时预览和远程回放行为进行统计, ...

  3. Spring Boot2(六):使用Spring Boot整合AOP面向切面编程

    一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop ​ aop全称Aspec ...

  4. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

  5. Javascript aop(面向切面编程)之around(环绕)

    Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...

  6. [转] AOP面向切面编程

    AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  7. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  8. 论AOP面向切面编程思想

    原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...

  9. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

随机推荐

  1. CentOS7 学习笔记

    1.首先centos7 采用了systemd管理系统服务的启动 systemd结合了以前红帽子的service 与chkconfig systemctl [command] [unit]   comm ...

  2. [转]程序员趣味读物:谈谈Unicode编码

    from : http://pcedu.pconline.com.cn/empolder/gj/other/0505/616631_all.html#content_page_1 这是一篇程序员写给程 ...

  3. win7系统网卡驱动正常,网线连接设备正常,但电脑右下角网络图片显示一直在转圈或者显示一个黄色感叹号的解决办法

    今天遇到一个问题是电脑的win7系统一直都可以连接有线,但今天突然连接不了.在我的电脑右键-->管理--->设备管理器-->网络适配器,里面查看了网络适配器安装正常.但是电脑右下角的 ...

  4. python关于分割与拼接的那些事

    1.split分割 基于re模块和正则表达式对象的方法split(),以后再做学习 基于字符串的split()方法 :字符串对象的split()方法也只能处理非常简单的情况,而且不支持多个分隔符,对分 ...

  5. PHP AES的加密解密

    AES加密算法 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DE ...

  6. Solr与MySQL查询性能对比

    本文简单对比下Solr与MySQL的查询性能速度. 测试数据量:10407608     Num Docs: 10407608 这里对MySQL的查询时间都包含了从MySQL Server获取数据的时 ...

  7. 重置VS设置

    用VS开发项目的时候, 偶发智能提示消失.关键字.类名不变色的情况. 如果你也遇到过,那么这样做: 新建txt,打开并输入以下内容: start "" "C:\Progr ...

  8. TDD学习笔记【二】---单元测试简介

    大纲 Testing 的第一个切入点:单元测试. 本篇文章将针对单元测试进行简介,主要内容包含了5W: Why What Where Who When 而How 的部分,属于实现部分,将于下一篇文章介 ...

  9. 前端知识杂烩(HTML[5]?+CSS篇)

    1. CSS 优先级算法如何计算?2.如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?3.用纯CSS创建一个三角形的原理是什么?4. 如何解决inline-block元素的空白间距( ...

  10. cout输出控制——位数和精度控制

    刷到一道需要控制输出精度和位数的题目 刚开始以为单纯使用 iomanip 函数库里的 setprecision 就可以,但 OJ 给我判了答案错误,后来一想这样输出并不能限制位数只能限制有效位数. 比 ...