文章

springAOP通知

springAOP通知1.什么是AOP通知2.通知的类型3.原理4.例子4.1创建一个spring项目4.2创建Java文件4.3创建xml文件4.4运行结果5.总结1.什么是AOP通知AOP通知就是面向切面编程中冗余的代码。比如在每次对数据库进行操作之前,需要记录操作的SQL语句,或者调用方法前打印方法名,这些就是AOP的通知。用大白话说,就是在横向业务中相同的操作,比如日志,事物,异常..._aop的通知是什么意思

springAOP通知

文章信息

  • 原文链接:https://jiayq.blog.csdn.net/article/details/87730393
  • 发布时间:2019-02-19 20:10:21
  • 阅读量:1
  • 分类:java同时被 3 个专栏收录, 订阅专栏, spring
  • 标签:#springAOP通知, #AOP通知类型, #实现自定义AOP, #jdk代理与cglib代理的环绕通知, #AOP通知类型详解与练习

摘要

文章浏览阅读1.1k次。springAOP通知1.什么是AOP通知2.通知的类型3.原理4.例子4.1创建一个spring项目4.2创建Java文件4.3创建xml文件4.4运行结果5.总结1.什么是AOP通知AOP通知就是面向切面编程中冗余的代码。比如在每次对数据库进行操作之前,需要记录操作的SQL语句,或者调用方法前打印方法名,这些就是AOP的通知。用大白话说,就是在横向业务中相同的操作,比如日志,事物,异常…_aop的通知是什么意思


springAOP通知

  • 1.什么是AOP通知
  • 2.通知的类型
  • 3.原理
  • 4.例子
    • 4.1创建一个spring项目
      • 4.2创建Java文件
      • 4.3创建xml文件
      • 4.4运行结果
  • 5.总结

1.什么是AOP通知

AOP通知就是面向切面编程中冗余的代码。
比如在每次对数据库进行操作之前,需要记录操作的SQL语句,或者调用方法前打印方法名,这些就是AOP的通知。
用大白话说,就是在横向业务中相同的操作,比如日志,事物,异常等等。

2.通知的类型

1.环绕通知
1.1 jdk代理
1.2 cglib代理
2.前置通知
3.后置通知
4.异常通知
5.引介通知

3.原理

ProxyFactoryBean是FactoryBean接口的实现类,FactoryBean负责实例化一个Bean,而ProxyFactoryBean负责为其他Bean创建代理实例。在spring中,使用ProxyFactoryBean是创建AOP代理的基本方式。

4.例子

4.1创建一个spring项目

在这里插入图片描述

4.2创建Java文件

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package aspect;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class AfterAspect implements AfterReturningAdvice{

   @Override
   public void afterReturning(Object returnValue, Method method,
   		Object[] args, Object target) throws Throwable {
   	
   	System.out.println("AfterAspect#afterReturning");
   	
   }

}




package aspect;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAspect implements MethodBeforeAdvice{

   @Override
   public void before(Method method, Object[] args, Object target)
   		throws Throwable {
   	
   	System.out.println("BeforeAspect#before");
   	
   }

}




package aspect;

import intf.PswdDao;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;

public class IntroductionAspect implements IntroductionInterceptor , PswdDao{

   @Override
   public Object invoke(MethodInvocation invocation) throws Throwable {
   	if(implementsInterface(invocation.getMethod().getDeclaringClass())){
   		return invocation.getMethod().invoke(this, invocation);
   	} else {
   		return invocation.proceed();
   	}
   }

   @Override
   public boolean implementsInterface(Class<?> intf) {
   	return intf.isAssignableFrom(PswdDao.class);
   }

   @Override
   public void sayPswd() {
   	System.out.println("Aspect#sayPswd");
   }


}




package aspect;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAspect implements MethodInterceptor{

   @Override
   public Object invoke(MethodInvocation arg0) throws Throwable {
   	before();
   	Object object = arg0.proceed();
   	after();
   	return object;
   }


   private void before(){
   	System.out.println("before");
   }
   
   private void after(){
   	System.out.println("after");
   }
   
}




package bean;

public class People {

   public void say(){
   	System.out.println("People#say");
   }
   
}




package client;

import intf.PswdDao;
import intf.UserDao;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import bean.People;

public class Main {

   public static void main(String[] args) {
   	
   	ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
   			"resource/*.xml");
   	UserDao userDao = (UserDao)applicationContext.getBean("userDaoInterceptorProxy");
   	userDao.add();
   	userDao.modify();
   	System.out.println();
   	People people = (People)applicationContext.getBean("peopleInterceptorProxy");
   	people.say();
   	System.out.println();
   	userDao = (UserDao)applicationContext.getBean("userDaoBeforeProxy");
   	userDao.add();
   	userDao.modify();
   	System.out.println();
   	userDao = (UserDao)applicationContext.getBean("userDaoAfterProxy");
   	userDao.add();
   	userDao.modify();
   	System.out.println();
   	userDao = (UserDao) applicationContext.getBean("pswdDaoInterceptorProxy");
   	userDao.add();
   	userDao.modify();
   	((PswdDao) userDao).sayPswd();
   }

}




package impl;

import intf.UserDao;

public class UserDaoImpl implements UserDao{

   @Override
   public void add() {
   	System.out.println("UserDaoImpl#add");
   }

   @Override
   public void modify() {
   	System.out.println("UserDaoImpl#modify");
   }

}




package intf;

public interface PswdDao {

   void sayPswd();
   
}




package intf;

public interface UserDao {

   void add();
   
   void modify();
   
}

4.3创建xml文件

bean.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd">
   <!-- 目标类 -->
   <bean id="userDao" class="impl.UserDaoImpl"></bean>
   <!-- 增强类 -->
   <bean id="aspect" class="aspect.MyAspect"></bean>
   <!-- 代理对象 -->
   <bean id="userDaoInterceptorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
   	<!-- 增强的接口 -->
   	<property name="proxyInterfaces">
   		<value>intf.UserDao</value>
   	</property>
   	<!-- 指定目标对象 -->
   	<property name="target" ref="userDao">
   	</property>
   	<!-- 指定增强类 -->
   	<property name="interceptorNames"> 
   		<value>aspect</value>
   	</property>
   	<property name="proxyTargetClass">
   		<value>false</value>
   	</property>
   </bean>
   <bean id="people" class="bean.People"></bean>
   <bean id="peopleInterceptorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
   	<!-- 指定目标对象 -->
   	<property name="target" ref="people">
   	</property>
   	<!-- 指定增强类 -->
   	<property name="interceptorNames"> 
   		<value>aspect</value>
   	</property>
   	<property name="proxyTargetClass">
   		<value>true</value>
   	</property>
   </bean>
   <bean id="userDaoBeforeProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
   	<!-- 增强的接口 -->
   	<property name="proxyInterfaces">
   		<value>intf.UserDao</value>
   	</property>
   	<!-- 指定目标对象 -->
   	<property name="target" ref="userDao">
   	</property>
   	<!-- 指定增强类 -->
   	<property name="interceptorNames"> 
   		<value>beforeAspect</value>
   	</property>
   	<property name="proxyTargetClass">
   		<value>false</value>
   	</property>
   </bean>
   <!-- 增强类 -->
   <bean id="beforeAspect" class="aspect.BeforeAspect"></bean>
   <!-- 增强类 -->
   <bean id="afterAspect" class="aspect.AfterAspect"></bean>
   <bean id="userDaoAfterProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
   	<!-- 增强的接口 -->
   	<property name="proxyInterfaces">
   		<value>intf.UserDao</value>
   	</property>
   	<!-- 指定目标对象 -->
   	<property name="target" ref="userDao">
   	</property>
   	<!-- 指定增强类 -->
   	<property name="interceptorNames"> 
   		<value>afterAspect</value>
   	</property>
   	<property name="proxyTargetClass">
   		<value>false</value>
   	</property>
   </bean>
   <bean id="intriductionAspect" class="aspect.IntroductionAspect"></bean>
   <bean id="pswdDaoInterceptorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
   	<!-- 增强的接口 -->
   	<property name="proxyInterfaces">
   		<value>intf.PswdDao</value>
   	</property>
   	<!-- 指定目标对象 -->
   	<property name="target" ref="intriductionAspect">
   	</property>
   	<!-- 指定增强类 -->
   	<property name="interceptorNames"> 
   		<value>intriductionAspect</value>
   	</property>
   	<property name="proxyTargetClass">
   		<value>false</value>
   	</property>
   </bean>
</beans>

4.4运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
before
UserDaoImpl#add
after
before
UserDaoImpl#modify
after

before
People#say
after

BeforeAspect#before
UserDaoImpl#add
BeforeAspect#before
UserDaoImpl#modify

UserDaoImpl#add
AfterAspect#afterReturning
UserDaoImpl#modify
AfterAspect#afterReturning

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy5 cannot be cast to intf.UserDao
   at client.Main.main(Main.java:32)

5.总结

spring的通知类型:
1.环绕通知
1.1 jdk代理
1.2 cglib代理
2.前置通知
3.后置通知
4.异常通知
5.引介通知

本文由作者按照 CC BY 4.0 进行授权