Spring AOP原理及拦截器Word文档格式.docx
- 文档编号:16638074
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:21
- 大小:34.62KB
Spring AOP原理及拦截器Word文档格式.docx
《Spring AOP原理及拦截器Word文档格式.docx》由会员分享,可在线阅读,更多相关《Spring AOP原理及拦截器Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。
Spring和其他纯JavaAOP框架一样,在运行时完成织入。
各种通知类型包括:
—
Around通知:
包围一个连接点的通知,如方法调用。
这是最强大的通知。
Aroud通知在方法调用前后完成自定义的行为,它们负责选择继续执行连接点或通过返回它们自己的返回值或抛出异常来短路执行。
Before通知:
在一个连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
Throws通知:
在方法抛出异常时执行的通知。
Spring提供强制类型的Throws通知,因此你可以书写代码捕获感兴趣的异常(和它的子类),不需要从Throwable或Exception强制类型转换。
Afterreturning通知:
在连接点正常完成后执行的通知,例如,一个方法正常返回,没有抛出异常。
Around通知是最通用的通知类型。
大部分基于拦截的AOP框架(如Nanning和Jboss4)只提供Around通知。
如同AspectJ,Spring提供所有类型的通知,我们推荐你使用最为合适的通知类型来实现需要的行为。
例如,如果只是需要用一个方法的返回值来更新缓存,你最好实现一个afterreturning通知,而不是around通知,虽然around通知也能完成同样的事情。
使用最合适的通知类型使编程模型变得简单,并能减少潜在错误。
例如,你不需要调用在around通知中所需使用的MethodInvocation的proceed()方法,因此就调用失败。
切入点的概念是AOP的关键,它使AOP区别于其他使用拦截的技术。
切入点使通知独立于OO的层次选定目标。
例如,提供声明式事务管理的around通知可以被应用到跨越多个对象的一组方法上。
因此切入点构成了AOP的结构要素。
拦截器(也称拦截机)
拦截机(Interceptor),是AOP(Aspect-OrientedProgramming)的另一种叫法。
AOP本身是一门语言,只不过我们使用的是基于JAVA的集成到Spring中的SpringAOP。
同样,我们将通过我们的例子来理解陌生的概念。
接口类
Java代码
1.<
SPAN
style="
FONT-SIZE:
medium"
>
package
com.test.TestSpring3;
2.
3.public
interface
UserService
//
被拦截的接口
4....{
5.
public
void
printUser(String
user);
6.}
7.<
/SPAN>
packagecom.test.TestSpring3;
publicinterfaceUserService//被拦截的接口
...{
publicvoidprintUser(Stringuser);
}
实现类
class
UserServiceImp
implements
实现UserService接口
user)
...{
6.
System.out.println("
printUser
user:
"
+
显示user
7.
}
8.}
9.
10.<
publicclassUserServiceImpimplementsUserService//实现UserService接口
publicvoidprintUser(Stringuser)...{
System.out.println("
printUseruser:
+user);
//显示user
}
AOP拦截器
3.import
org.aopalliance.intercept.MethodInterceptor;
4.import
org.aopalliance.intercept.MethodInvocation;
6.public
UserInterceptor
MethodInterceptor
7.//
AOP方法拦截器
8....{
10.
Object
invoke(MethodInvocation
arg0)
throws
Throwable
11.
12.
try
13.
14.
if
(arg0.getMethod().getName().equals("
printUser"
))
15.
拦截方法是否是UserService接口的printUser方法
16.
17.
Object[]
args
=
arg0.getArguments();
被拦截的参数
18.
args[0]);
19.
arg0.getArguments()[0]
hello!
;
修改被拦截的参数
20.
21.
22.
23.
System.out.println(arg0.getMethod().getName()
---!
);
24.
return
arg0.proceed();
运行UserService接口的printUser方法
25.
26.
}
catch
(Exception
e)
27.
throw
e;
28.
29.
30.}
31.<
<
32.<
importorg.aopalliance.intercept.MethodInterceptor;
importorg.aopalliance.intercept.MethodInvocation;
publicclassUserInterceptorimplementsMethodInterceptor
//AOP方法拦截器
publicObjectinvoke(MethodInvocationarg0)throwsThrowable...{
try...{
if(arg0.getMethod().getName().equals("
))
//拦截方法是否是UserService接口的printUser方法
...{
Object[]args=arg0.getArguments();
//被拦截的参数
+args[0]);
arg0.getArguments()[0]="
//修改被拦截的参数
System.out.println(arg0.getMethod().getName()+"
returnarg0.proceed();
//运行UserService接口的printUser方法
}catch(Exceptione)...{
throwe;
测试类
org.springframework.beans.factory.BeanFactory;
4.
5.import
org.springframework.beans.factory.xml.XmlBeanFactory;
6.import
org.springframework.context.ApplicationContext;
7.import
org.springframework.context.support.ClassPathXmlApplicationContext;
8.import
org.springframework.context.support.FileSystemXmlApplicationContext;
9.import
org.springframework.core.io.ClassPathResource;
10.import
org.springframework.core.io.Resource;
11.import
org.springframework.web.context.support.WebApplicationContextUtils;
13.public
TestInterceptor
static
main(String[]
args)
ApplicationContext
ctx
new
FileSystemXmlApplicationContext(
classpath:
applicationContext.xml"
18.//
ClassPathXmlApplicationContext("
us
(UserService)
ctx.getBean("
userService"
us.printUser("
shawn"
24.}<
25.<
importorg.springframework.beans.factory.BeanFactory;
importorg.springframework.beans.factory.xml.XmlBeanFactory;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importorg.springframework.context.support.FileSystemXmlApplicationContext;
importorg.springframework.core.io.ClassPathResource;
importorg.springframework.core.io.Resource;
importorg.springframework.web.context.support.WebApplicationContextUtils;
publicclassTestInterceptor...{
publicstaticvoidmain(String[]args)...{
ApplicationContextctx=newFileSystemXmlApplicationContext(
"
//ApplicationContextctx=newClassPathXmlApplicationContext("
UserServiceus=(UserService)ctx.getBean("
us.printUser("
配置文件
Xml代码
?
xml
version="
1.0"
encoding="
UTF-8"
2.<
!
DOCTYPE
beans
PUBLIC
-//SPRING//DTD
BEAN//EN"
http:
//www.springframework.org/dtd/spring-beans.dtd"
3.<
beans>
bean
id="
userServiceImp"
class="
com.test.TestSpring3.UserServiceImp"
/>
userInterceptor"
com.test.TestSpring3.UserInterceptor"
8.
org.springframework.aop.framework.ProxyFactoryBean"
--
代理接口
-->
property
name="
proxyInterfaces"
value>
com.test.TestSpring3.UserService<
/value>
/property>
目标实现类
target"
ref
local="
拦截器
interceptorNames"
list>
userInterceptor<
/list>
/bean>
27.<
/beans>
28.<
xmlversion="
encoding="
DOCTYPEbeansPUBLIC"
-//SPRING//DTDBEAN//EN"
<
beanid="
class="
/>
--代理接口-->
propertyname="
--目标实现类-->
reflocal="
--拦截器-->
输出:
user:
shawn
printUser---!
printUser
结论:
调用方法的时候
传入的值被拦截修改了.
拦截器中的事务管理(事务拦截机)
如果不采用拦截机的机制时,在使用JDBC进行数据库访问时,存在两种情况:
∙自动提交
这是JDBC驱动默认的模式,每次数据库操作(CRUD)成功完成后,都作为一个单独的事务自动提交,如果未成功完成,即抛出了SQLException的话,仅最近的一个操作将回滚。
∙非自动提交
这是想更好的控制事务时需要程序地方式进行控制:
o在进行该事务单元的任何操作之前setAutoCommit(false)
o在成功完成事务单元后commit()
o在异常发生后rollback()
自动提交模式是不被推荐的,因为每个操作都将产生一个事务点,这对于大的应用来说性能将受到影响;
再有,对于常见的业务逻辑,这种模式显得无能为力。
比如:
转帐,从A帐户取出100元,将其存入B帐户;
如果在这两个操作之间发生了错误,那么用户A将损失了100元,而本来应该给帐户B的,却因为失败给了银行。
所以,建议在所有的应用中,如果使用JDBC都将不得不采用非自动提交模式(你们要能发现了在我们的JDBC那个例子中,我们采用的就是自动提交模式,我们是为了把精力放在JDBC上,而不是事务处理上),即我们不得不在每个方法中:
{
在获得连接后,立即通过调用 setAutoCommit(false)
将事务处理置为非自动提交模式
Prepare
Query
to
fetch
the
user
Information
3.
pst
conn.prepareStatement(findByName);
...
mit();
catch(Exception
ex)
conn.rollback();
ex;
}finally
{
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring AOP原理及拦截器 AOP 原理 拦截