Spring 2.5 采用动态代理或cglib来实现aop
来源:互联网 发布:自学php需要什么基础 编辑:程序博客网 时间:2024/04/26 00:52
动态代理,cglib,aop
1)
public class JDKProxy implements InvocationHandler {
private Object targetObject;//代理的目标对象
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
/*
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean bean=(PersonServiceBean)this.targetObject;
Object result=null
if(bean.getUser()!=null){
result=method.invoke(this.targetObject, args);//把方法调用委派给目标对象
}
return result;
}
}
2)
public class PersonServiceBean implements PersonService{
private String user=null;
public String getUser(){
return user;
}
public PersonServiceBean(){}
public PersonServiceBean(String user){
this.user=user;
}
public void save(String name){
System.out.println("我是save()方法");
}
}
3)
JDKProxy factory=new JDKProxy();
PersonService service=(PersonService)factory.createProxyInstance(new PersonServiceBean("xxx"));
service.save("888");
4)如果PersonServiceBean 没有实现PersonService
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibProxyFactory implements MethodInterceptor{
private Object targetObject;
public Object createProxyInstance(Object targetObject){
this.targetObject=targetObject;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());//非final修饰符的所有方法
enhacer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean bean=(PersonServiceBean)this.targetObject;
Object result=null
if(bean.getUser()!=null){
//advice()-->前置通知
try{
result=methodProxy .invoke(this.targetObject, args);//把方法调用委派给目标对象
//afteradvice()-->后置通知
}catch(RuntimeException e){
//exceptionadvice()--〉例外通知
}finally{
//finallyadvice() -->最终通知
}
}
return result;
}
}
还有一种通知叫-->环绕通知
5)相应测试代码如下
CGlibProxyFactory factory=new CGlibProxyFactory();
PersonServiceBean service=(PersonServiceBean)factory.createProxyInstace(new PersonServiceBean("xxx"));
service.save("99");
6)
Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,
类是对物体特征的抽象,而切面横切性关注点的抽象.
joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,
因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)
Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.
Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知
Target(目标对象):代理的目标对象
Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.
Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
7)
要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:
<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-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
</beans>
Spring提供了两种切面声明方式,实际工作中我们可以选用其中一种:
基于XML配置方式声明切面。
基于注解方式声明切面。
8) 使用注释方式 进行aop开发要在applicationContext中加入<aop:aspectj-autoproxy/>
在类前加入@Aspect
把这个拦载类放到spring的配置文件 中
<bean id="myInterceptor" class="cn.itcast.service.MyInterceptor" />
@Aspect
public class MyInterceptor{
@Pointcut("execution(* cn.itcast.service..*.*(..))")
private void anyMethod() {}//声明一个切入点
@Before("anyMethod() && args(userName)")//定义前置通知 并且此前置通知只拦截带有一个参数,且类型为String的方法
public void doAccessCheck(String userName) {
}
@AfterReturning(pointcut="anyMethod()",returning="result")//定义后置通知
public void doReturnCheck(String result) {
}
@AfterThrowing(pointcut="anyMethod()", throwing="ex")//定义例外通知
public void doExceptionAction(Exception ex) {
}
@After("anyMethod()")//定义最终通知
public void doReleaseAction() {
}
@Around("anyMethod()")//环绕通知
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();//确保后面的切面和业务bean都得到执行
//适合作为权限拦截的处理
}
}
前置通知-->环绕通知-->业务方法-->后置通知--->最终通知-->环绕通知
前置通知->业务方法-->异常通知-->最终通知
8) 使用配置文件 进行aop开发
普通的类定义
public class LogPrint {
public void doAccessCheck() {}定义前置通知
public void doReturnCheck() {}定义后置通知
public void doExceptionAction() {}定义例外通知
public void doReleaseAction() {}定义最终通知
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();环绕通知
}
}
<bean id="orderservice" class="cn.itcast.service.OrderServiceBean"/>
<bean id="log" class="cn.itcast.service.LogPrint"/>
<aop:config>
<aop:aspect id="myaop" ref="log">
<aop:pointcut id="mycut" expression="execution(* cn.itcast.service..*.*(..))"/>
<aop:before pointcut-ref="mycut" method="doAccessCheck"/>
<aop:after-returning pointcut-ref="mycut" method="doReturnCheck "/>
<aop:after-throwing pointcut-ref="mycut" method="doExceptionAction"/>
<aop:after pointcut-ref="mycut" method=“doReleaseAction"/>
<aop:around pointcut-ref="mycut" method="doBasicProfiling"/>
</aop:aspect>
</aop:config>
9)execution(java.lang.String cn.itcast.service..*.*(..)) //拦截返回值为String service包下及其子包的所有类的所有方法
execution(* cn.itcast.service..*.*(java.lang.String,..)) //拦截方法的第一个参数是String,其他参数不限,包括只有一个参数
execution(!void cn.itcast.service..*.*(..)) //返回值不是void
execution(* cn.itcast.service.impl.PersonServiceBean.*(..))
- Spring 2.5 采用动态代理或cglib来实现aop
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- cglib 动态代理实现AOP
- Spring AOP的底层实现技术---CGLib动态代理
- spring对AOP的支持(JDK的动态代理实现AOP和CGLIB实现AOP)
- Spring AOP 代理实现的两种方式: JDK动态代理 和 Cglib框架动态代理
- Spring AOP基础-CGLib动态代理
- jdk动态代理与cglib代理、spring aop代理实现原理
- CGLIB动态代理和JDK动态代理-Spring AOP的底层实现原理
- Spring AOP底层实现- JDK动态代理和CGLIB动态代理
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
- spring AOP 两种底层实现( JDK动态代理 和 CGLIB代理)
- spring AOP 动态代理 jkd动态代理和cglib动态代理 hibernate使用cglib延迟加载
- AOP的底层实现--JDK动态代理,CGLIB动态代理
- 动态代理实现AOP与cglib实现AOP
- Spring AOP中的JDK动态代理与CGLIB代理
- 一些好笑的话
- Killer's sentence too light!
- 欢迎光临!
- 防止android应用的内存泄露
- spring servlet
- Spring 2.5 采用动态代理或cglib来实现aop
- 多层数据库应用基于Delphi DataSnap方法调用的实现(三)对象池技术
- 通用的自动提交From表单
- pyqt 在QTreeView里使用复选框checkbox
- Ubuntu 10.04(64位)下载并编译 Android 2.2 源码[只有11条命令]
- grub4dos 从硬盘引导安装 ubuntu
- 报告一个小小bug
- POJ 1724 ROADS
- MYSQL索引使用