目录标题
- 一、Sprig的AOP操作
- JDK动态代理
- CGLib动态代理
- 基于xml开发Spring AOP
- 基于注解开发Spring AOP
- 二、多切面的顺序
- 基于注解的配置
- 基于Ordered接口配置
- 基于XML配置
- 三、性能及异常监控
- 性能监控
- 异常监控
- 四、工程目录及运行结果图
一、Sprig的AOP操作
JDK动态代理
//接口
package com.qfedu.demo01;
/**
* @author 123
*/ //LoginService接口
public interface LoginService {
public void login();
}
//实现类
package com.qfedu.demo01;
/**
* @author 123
*/
public class LoginServiceImpl implements LoginService{
public void login() {
System.out.println("执行login方法");
}
}
package com.qfedu.demo01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformHandler implements InvocationHandler {
// 目标对象
private Object target;
public PerformHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 增强的方法
System.out.println("方法开始执行");
// 执行被代理类的原方法
Object invoke = method.invoke(target, args);
// 增强的方法
System.out.println("方法执行完毕");
return invoke;
}
}
//测试类
package com.qfedu.demo01;
import java.lang.reflect.Proxy;
public class TestPerformHandler {
public static void main(String[] args) {
LoginService loginService = new LoginServiceImpl();
PerformHandler performHandler = new PerformHandler(loginService);
// 创建代理对象
loginService = (LoginService)Proxy.newProxyInstance(loginService.getClass().getClassLoader(),
loginService.getClass().getInterfaces(), performHandler);
loginService.login();
}
}
CGLib动态代理
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>chapter08</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
</dependencies>
</project>
package com.qfedu.demo01;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibPoxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
// 生成代理对象的方法
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGLig代理之前");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("CGLig代理之后");
return null;
}
}
package com.qfedu.demo01;
public class TestCGLlib {
public static void main(String[] args) {
CglibPoxy cglibPoxy = new CglibPoxy();
// 创建代理对象
LoginServiceImpl userService = (LoginServiceImpl) cglibPoxy.getProxy(LoginServiceImpl.class);
userService.login();
}
}
基于xml开发Spring 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"
xmlns:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="userService" class="com.qfedu.demo02.UserServiceImpl"></bean>
<bean name="xmlAdvice" class="com.qfedu.demo02.XmlAdvice"></bean>
<!--配置Spring AOP-->
<aop:config>
<!-- 指定切点-->
<aop:pointcut id="pointcut" expression="execution( * com.qfedu.demo02.UserServiceImpl.*(..))"/>
<!-- 制定切面-->
<aop:aspect ref="xmlAdvice">
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"></aop:after-returning>
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
<aop:after-throwing method="afterException" pointcut-ref="pointcut"></aop:after-throwing>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
</aop:config>
</beans>
package com.qfedu.demo02;
public interface UserService {
void insert();
void delete();
void update();
void select();
}
package com.qfedu.demo02;
public class UserServiceImpl implements UserService{
public void insert() {
System.out.println("添加用户信息");
}
public void delete() {
System.out.println("删除用户信息");
}
public void update() {
System.out.println("更新用户信息");
}
public void select() {
System.out.println("查询用户信息");
}
}
package com.qfedu.demo02;
import org.aspectj.lang.ProceedingJoinPoint;
public class XmlAdvice {
// 前置通知
public void before(){
System.out.println("此为前置通知");
}
// 后置通知
public void afterReturning(){
System.out.println("此为后置通知(无异常)");
}
// 环绕通知
public Object around(ProceedingJoinPoint point) throws Throwable{
System.out.println("此为环绕通知之前的部分");
Object object = point.proceed();
System.out.println("此为环绕通知之后的部分");
return object;
}
// 异常通知
public void afterException(){
System.out.println("此为异常通知");
}
// 后置通知
public void after(){
System.out.println("此为后置通知");
}
}
package com.qfedu.demo02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestXml {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.delete();
}
}
基于注解开发Spring 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"
xmlns:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="userService" class="com.qfedu.demo02.UserServiceImpl"></bean>
<bean name="xmlAdvice" class="com.qfedu.demo02.XmlAdvice"></bean>
<!--配置Spring AOP-->
<aop:config>
<!-- 指定切点-->
<aop:pointcut id="pointcut" expression="execution( * com.qfedu.demo02.UserServiceImpl.*(..))"/>
<!-- 制定切面-->
<aop:aspect ref="xmlAdvice">
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"></aop:after-returning>
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
<aop:after-throwing method="afterException" pointcut-ref="pointcut"></aop:after-throwing>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
</aop:config>
<!-- 注册bean-->
<!-- <bean name="userService" class="com.qfedu.demo02.UserServiceImpl"/>-->
<bean name="annoAdvice" class="com.qfedu.demo02.AnnoAdvice"/>
<!-- 开启@aspectj的自动代理支持-->
<aop:aspectj-autoproxy/>
</beans>
package com.qfedu.demo02;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
public class AnnoAdvice {
//切点
@Pointcut("execution( * com.qfedu.demo02.UserServiceImpl. * (..))")
public void pointcut(){
}
// 前置通知
@Before("pointcut()")
public void before(){
System.out.println("此为前置通知");
}
// 后置通知
@AfterReturning("pointcut()")
public void afterReturning(){
System.out.println("此为后置通知(无异常)");
}
// 环绕通知
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable{
System.out.println("此为环绕通知之前的部分");
Object object = point.proceed();
System.out.println("此为环绕通知之后的部分");
return object;
}
// 异常通知
@AfterThrowing("pointcut()")
public void afterException(){
System.out.println("此为异常通知");
}
// 后置通知
@After("pointcut()")
public void after(){
System.out.println("此为后置通知");
}
}
package com.qfedu.demo02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAnnotation {
public static void main(String[] args) {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.insert();
}
}
二、多切面的顺序
基于注解的配置
@Order(0):数字越小,优先级越高
<?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:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="userService" class="com.qfedu.demo02.UserServiceImpl"/>
<!-- <bean name="xmlAdvice" class="com.qfedu.demo02.XmlAdvice"/>-->
<!-- <bean name="annoAdvice" class="com.qfedu.demo02.AnnoAdvice"/>-->
<bean name="aspect01" class="com.qfedu.demo02.Aspect01"/>
<bean name="aspect02" class="com.qfedu.demo02.Aspect02"/>
<!-- 开启@aspectj的自动代理支持/扫描包设置-->
<aop:aspectj-autoproxy/>
<!--<!–配置Spring AOP–>-->
<!-- <aop:config>-->
<!--<!– 指定切点–>-->
<!-- <aop:pointcut id="pointcut" expression="execution( * com.qfedu.demo02.UserServiceImpl.*(..))"/>-->
<!--<!– 制定切面–>-->
<!-- <aop:aspect ref="xmlAdvice">-->
<!-- <aop:before method="before" pointcut-ref="pointcut"></aop:before>-->
<!-- <aop:after-returning method="afterReturning" pointcut-ref="pointcut"></aop:after-returning>-->
<!-- <aop:around method="around" pointcut-ref="pointcut"></aop:around>-->
<!-- <aop:after-throwing method="afterException" pointcut-ref="pointcut"></aop:after-throwing>-->
<!-- <aop:after method="after" pointcut-ref="pointcut"></aop:after>-->
<!-- </aop:aspect>-->
<!-- </aop:config>-->
</beans>
package com.qfedu.demo02;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
@Aspect
@Order(1)
public class Aspect01 {
// 切点
@Pointcut("execution(* com.qfedu.demo02.UserServiceImpl.*(..))")
public void pointcut(){
}
// 前置通知
@Before("pointcut()")
public void before(){
System.out.println("这是Aspect01前置通知");
}
// 后置通知
@After("pointcut()")
public void after(){
System.out.println("这是Aspect01后置通知");
}
}
package com.qfedu.demo02;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
@Aspect
@Order(0)
public class Aspect02 {
// 切点
@Pointcut("execution(* com.qfedu.demo02.UserServiceImpl.*(..))")
public void pointcut(){
}
// 前置通知
@Before("pointcut()")
public void before(){
System.out.println("这是Aspect02前置通知");
}
// 后置通知
@After("pointcut()")
public void after(){
System.out.println("这是Aspect02后置通知");
}
}
package com.qfedu.demo02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAspect {
public static void main(String[] args) {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.select();
}
}
基于Ordered接口配置
<?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:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="userService" class="com.qfedu.demo02.UserServiceImpl"/>
<!-- <bean name="xmlAdvice" class="com.qfedu.demo02.XmlAdvice"/>-->
<!-- <bean name="annoAdvice" class="com.qfedu.demo02.AnnoAdvice"/>-->
<!-- <bean name="aspect01" class="com.qfedu.demo02.Aspect01"/>-->
<!-- <bean name="aspect02" class="com.qfedu.demo02.Aspect02"/>-->
<bean name="aspect03" class="com.qfedu.demo02.Aspect03"/>
<bean name="aspect04" class="com.qfedu.demo02.Aspect04"/>
<!-- 开启@aspectj的自动代理支持/扫描包设置-->
<aop:aspectj-autoproxy/>
<!--<!–配置Spring AOP–>-->
<!-- <aop:config>-->
<!--<!– 指定切点–>-->
<!-- <aop:pointcut id="pointcut" expression="execution( * com.qfedu.demo02.UserServiceImpl.*(..))"/>-->
<!--<!– 制定切面–>-->
<!-- <aop:aspect ref="xmlAdvice">-->
<!-- <aop:before method="before" pointcut-ref="pointcut"></aop:before>-->
<!-- <aop:after-returning method="afterReturning" pointcut-ref="pointcut"></aop:after-returning>-->
<!-- <aop:around method="around" pointcut-ref="pointcut"></aop:around>-->
<!-- <aop:after-throwing method="afterException" pointcut-ref="pointcut"></aop:after-throwing>-->
<!-- <aop:after method="after" pointcut-ref="pointcut"></aop:after>-->
<!-- </aop:aspect>-->
<!-- </aop:config>-->
</beans>
package com.qfedu.demo02;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
@Aspect
public class Aspect03 implements Ordered {
@Pointcut("execution(* com.qfedu.demo02.UserServiceImpl.*(..))")
public void pointcut(){
}
// 前置通知
@Before("pointcut()")
public void before(){
System.out.println("这是Aspect03前置通知");
}
// 后置通知
@After("pointcut()")
public void after(){
System.out.println("这是Aspect03后置通知");
}
//返回指定切面的优先级
public int getOrder() {
return 1;
}
}
package com.qfedu.demo02;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
@Aspect
public class Aspect04 implements Ordered {
@Pointcut("execution(* com.qfedu.demo02.UserServiceImpl.*(..))")
public void pointcut(){
}
// 前置通知
@Before("pointcut()")
public void before(){
System.out.println("这是Aspect04前置通知");
}
// 后置通知
@After("pointcut()")
public void after(){
System.out.println("这是Aspect04后置通知");
}
//返回指定切面的优先级
public int getOrder() {
return 2;
}
}
基于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"
xmlns:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="userService" class="com.qfedu.demo02.UserServiceImpl"/>
<bean name="aspect05" class="com.qfedu.demo02.Aspect05"/>
<bean name="aspect06" class="com.qfedu.demo02.Aspect06"/>
<!--配置Spring AOP-->
<aop:config>
<!-- 指定切点-->
<aop:pointcut id="pointcut" expression="execution( * com.qfedu.demo02.UserServiceImpl.*(..))"/>
<!-- 制定切面-->
<aop:aspect ref="aspect05" order="1">
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
<aop:aspect ref="aspect06" order="2">
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
</aop:config>
</beans>
package com.qfedu.demo02;
public class Aspect05 {
public void before(){
System.out.println("这是Aspect05的前置通知");
}
public void after(){
System.out.println("这是Aspect05的后置通知");
}
}
package com.qfedu.demo02;
public class Aspect06 {
public void before(){
System.out.println("这是Aspect06的前置通知");
}
public void after(){
System.out.println("这是Aspect06的后置通知");
}
}
三、性能及异常监控
性能监控
<?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:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="service01" class="com.qfedu.demo03.Service01"/>
<bean name="recordAspect" class="com.qfedu.demo03.RecordAspect"/>
<aop:aspectj-autoproxy/>
</beans>
package com.qfedu.demo03;
public class Service01 {
public void service() throws InterruptedException {
System.out.println("执行service()方法");
Thread.sleep(1000);
}
}
package com.qfedu.demo03;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Date;
@Aspect
public class RecordAspect {
//切点
@Pointcut("execution( * com.qfedu.demo03.Service*.*(..))")
public void record(){
}
@Around("record()")
public Object recordTimer(ProceedingJoinPoint thisJoinPoint) throws Throwable{
// 获取目标对象类名称
String className = thisJoinPoint.getTarget().getClass().getName();
// 方法名称
String methodaName = thisJoinPoint.getSignature().getName();
// 消耗时间
long startTime = System.currentTimeMillis();
Object result = thisJoinPoint.proceed();
long time = System.currentTimeMillis()-startTime;
Record record = new Record();
record.setExpendTime(time);
record.setClassName(className);
record.setMethodName(methodaName);
record.setRecordTime(new Date());
System.out.println(record.toString());
return result;
}
}
package com.qfedu.demo03;
import java.util.Date;
public class Record {
// 类名称
private String className;
// 方法名称
private String methodName;
// 记录时间
private Date recordTime;
// 程序执行耗费时间
private Long expendTime;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Date getRecordTime() {
return recordTime;
}
public void setRecordTime(Date recordTime) {
this.recordTime = recordTime;
}
public Long getExpendTime() {
return expendTime;
}
public void setExpendTime(Long expendTime) {
this.expendTime = expendTime;
}
@Override
public String toString() {
return "Record{" +
"className='" + className + '\'' +
", methodName='" + methodName + '\'' +
", recordTime=" + recordTime +
", expendTime=" + expendTime +
'}';
}
}
package com.qfedu.demo03;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestRecord {
public static void main(String[] args) throws InterruptedException {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext_record.xml");
Service01 service01 = context.getBean("service01", Service01.class);
service01.service();
}
}
异常监控
<?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:contxt="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 注册bean-->
<bean name="service02" class="com.qfedu.demo03.Service02"/>
<bean name="messageAspect" class="com.qfedu.demo03.MessageAspect"/>
<aop:aspectj-autoproxy/>
</beans>
package com.qfedu.demo03;
import java.util.Date;
public class Message {
private String className;
private String methodName;
private Date recordTime;
private String exceptionMsg;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Date getRecordTime() {
return recordTime;
}
public void setRecordTime(Date recordTime) {
this.recordTime = recordTime;
}
public String getExceptionMsg() {
return exceptionMsg;
}
public void setExceptionMsg(String exceptionMsg) {
this.exceptionMsg = exceptionMsg;
}
@Override
public String toString() {
return "Message{" +
"className='" + className + '\'' +
", methodName='" + methodName + '\'' +
", recordTime=" + recordTime +
", exceptionMsg='" + exceptionMsg + '\'' +
'}';
}
}
package com.qfedu.demo03;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import java.util.Date;
@Aspect
public class MessageAspect {
//切点
@Pointcut("execution( * com.qfedu.demo03.Service*.*(..))")
public void exectionMsg(){
}
@Around("exectionMsg()")
public Object msgMethod(ProceedingJoinPoint thisJoinPoint) throws Throwable{
// 获取目标对象类名称
String className = thisJoinPoint.getTarget().getClass().getName();
// 方法名称
String methodaName = thisJoinPoint.getSignature().getName();
try{
return thisJoinPoint.proceed();
}catch (MyException e){
Message msg = new Message();
msg.setClassName(thisJoinPoint.getTarget().getClass().getName());
msg.setMethodName(thisJoinPoint.getSignature().getName());
msg.setRecordTime(new Date());
msg.setExceptionMsg(e.getMsg());
System.out.println(msg.toString());
return null;
}
}
}
package com.qfedu.demo03;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMessage {
public static void main(String[] args) throws Exception {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext_msg.xml");
Service02 service02 = context.getBean("service02", Service02.class);
service02.service();
}
}
package com.qfedu.demo03;
public class Service02 {
public void service() throws Exception{
System.out.println("执行Service()方法");
int num = 105;
if(num>100||num<0){
throw new MyException("您输入的不正确,请输入0~100之间的数字");
}else {
System.out.println("您输入的数字是"+num);
}
}
}
package com.qfedu.demo03;
public class MyException extends Exception{
private static final long serialVersionUID = 1L;
private String msg;
MyException(String msg){
super();
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
四、工程目录及运行结果图
demo1和demo2的目录
JDK动态代理
CGLib动态代理
基于xml开发Spring AOP
基于注解开发Spring AOP
基于注解的配置
基于Ordered接口配置
基于XML配置
demo3目录
性能监控
异常监控