spring之AOP(⾯向切⾯编程)和五⼤通知(前置通知、后置通知、异常通知、环绕通知、过滤通知)
⼀、aop的介绍
1.AOP中关键性概念:
连接点(Joinpoint):程序执⾏过程中明确的点,如⽅法的调⽤,或者异常的抛出.
⽬标(Target):被通知(被代理)的对象
注1:完成具体的业务逻辑
通知(Advice):在某个特定的连接点上执⾏的动作,同时Advice也是程序代码的具体实现,例如⼀个实现⽇志记录的代码(通知有些书上也称为处理)
注2:完成切⾯编程
代理(Proxy):将通知应⽤到⽬标对象后创建的对象(代理=⽬标+通知),
例⼦:外科医⽣+护⼠
注3:只有代理对象才有AOP功能,⽽AOP的代码是写在通知的⽅法⾥⾯的
切⼊点(Pointcut):多个连接点的集合,定义了通知应该应⽤到那些连接点。
(也将Pointcut理解成⼀个条件 ,此条件决定了容器在什么情况下将通知和⽬标组合成代理返回给外部程序)
适配器(Advisor):适配器=通知(Advice)+切⼊点(Pointcut)
先⽬标---通知---连接点---⽬标---代理
2.如何实现AOP
⽬标对象只负责业务逻辑代码
通知对象负责AOP代码,这⼆个对象都没有AOP的功能,只有代理对象才有
3.aop核⼼点:
通知
类型 实现接⼝ 应⽤场景
前置通知 实现org.springframework.aop.MethodBeforeAdvice接⼝
买书、评论前加系
统⽇志
后置
通知
实现org.springframework.aop.AfterReturningAdvice接⼝ 买书返利
环绕通知 实现org.aopalliance.intercept.MethodInterceptor接⼝
类似,会包括
切⼊点,⽬标类前后
都会执⾏代码
异常通知实现org.springframework.aop.ThrowsAdvice接⼝
出现异常执⾏系统提
⽰,然后进⾏处理。
价格异常为例
过滤
通知(适配器) 实现
org.springframework.aop.support.RegexpMethodPointcutAdvisor
接⼝
处理买书返利的bug
⼆、前置通知
前置通知(org.springframework.aop.MethodBeforeAdvice):在连接点之前执⾏的通知()
案例:在购书系统当中使⽤AOP⽅式实现⽇志系统
异常类
package com.ption;
public class PriceException extends RuntimeException {
//价格异常
public PriceException() {
super();
}
public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace);
}
public PriceException(String message, Throwable cause) {
super(message, cause);
}
public PriceException(String message) {
super(message);
}
public PriceException(Throwable cause) {
super(cause);
}
}
接⼝IBookBiz有两个⽅法
package com.xhy.aop.biz;
public interface IBookBiz {
// 购书
public boolean buy(String userName, String bookName, Double price);
// 发表书评
public void comment(String userName, String comments);
}
实现类BookBizImpl 继承接⼝ 并重写⽅法
package com.xhy.aop.biz.impl;
import com.xhy.aop.biz.IBookBiz;
import com.ption.PriceException;
public class BookBizImpl implements IBookBiz {
public BookBizImpl() {
super();
}
public boolean buy(String userName, String bookName, Double price) { // 通过控制台的输出⽅式模拟购书
if (null == price || price <= 0) {
throw new PriceException("book price exception");
}
System.out.println(userName + " buy " + bookName + ", spend " + price);
return true;spring aop应用场景
}
public void comment(String userName, String comments) {
// 通过控制台的输出⽅式模拟发表书评
System.out.println(userName + " say:" + comments);
}
}
前置通知MyMethodBeforeAdvice 实现⼀个接⼝ 类代码
package com.xhy.aop.advice;
import flect.Method;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
/**
* 调⽤项⽬中的某⼀接⼝实现类的⽅式时,将类名.⽅法名,携带的参数,作为⽇志存储到数据库。
* @author Administrator
*
*/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
/**target:⽬标对象
* method:被触发的⽬标对象的⽅法对象
* args:⽬标对象的⽬标⽅法的携带的参数
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
String targetName = Class().getName();
String methodName = Name();
String params = String(args);
String msg = "【系统⽇志】:正在调⽤->"+targetName+"."+methodName+",携带的参数:"+params;
System.out.println(msg);
}
}
配置l
<!-- ⽬标 -->
<bean name="bookBiz" class="com.xhy.aop.biz.impl.BookBizImpl"></bean>
常规业务代码AopTest(测试)
package com.st;
import t.ApplicationContext;
import t.support.ClassPathXmlApplicationContext;
import com.xhy.aop.biz.IBookBiz;
public class AopTest {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/l");
IBookBiz bookBiz =(IBookBiz) Bean("bookBiz");
bookBiz.buy("⼩慧", "鲁宾孙漂流记", 9.9d);
bookBizment("⼩慧", "我很开⼼啊");
}
}
运⽤:
配置⽂件中l:
<!-- 前置通知 -->
<bean name="myBefore" class="com.xhy.aop.advice.MyMethodBeforeAdvice"></bean>
<!-- ⽣成代理(⽬标对象+通知) -->
<bean class="org.springframework.aop.framework.ProxyFactoryBean"
id="proxyFactoryBean">
<property name="target" ref="bookBiz"></property>
<!-- 代理⼯⼚⽣产的代理需要实现的接⼝列表 -->
<property name="proxyInterfaces">
<list>
<value>com.xhy.aop.biz.IBookBiz</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>myBefore</value>
</list>
</property>
</bean>
拿到代理对象:
package com.st;
import t.ApplicationContext;
import t.support.ClassPathXmlApplicationContext;
import com.xhy.aop.biz.IBookBiz;
public class AopTest {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/l");
IBookBiz bookBiz =(IBookBiz) Bean("proxyFactoryBean");
bookBiz.buy("⼩慧", "鲁宾孙漂流记", 9.9d);
bookBizment("⼩慧", "我很开⼼啊");
}
}
运⾏结果:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论