如果你是spring的老用户,又或者你的jdk没有1.5;又或者你想很清晰地看出系统存在那些切面. 无注释,全配置aop最适合怀旧的你
aop全配置标签 :
1.config----->三标签:pointcut;advisor;aspect(必须按此顺序来写属性)-------->aspect标签含七个标签---------->pointcut;declare-parents;before;after;after-returning;after-throwing;around.
1.1aspect有三属性1.1.1----->id(定义该bean组件的标识)
1.1.2----->ref(这个词是能够全配置的关键词,将全配置文件(该文件是没有class地址的引向有地址的纯<bean>标签)) eg <aop:aspect id="xxxx" ref="beanid"> <bean id="beanid" class="xxxxx">就这样将全配置摔给了bean标签并成为bean组件
1.1.3----->order:指定该切面bean的优先级别,值小优先级越高.
1.2pointcut:用来定义切入点,它有两个属性------->id:切入点id(标识) 是赋值给pointcut-ref让拥有该属性的标签可以使用pointcut表达式
expression:切入点表达式
问题1:config既然已经有了pointcut属性,为什么aspect还要有了???因为:config下pointcut是全局切入点,而aspect下的pointcut属性仅是该标签下的切入点,作用范围不同
1.3advisor:用来定义一个通知和一个切入点的切面(和aspect的区别在于数量)
我的第一个全配置aop例子
切面
package test;
import java.util.Arrays;
import org.aopalliance.intercept.Joinpoint;
import org.apache.commons.logging.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class aspect1 {
public Object processTx(ProceedingJoinPoint jp) throws Throwable {
System.out.println("around增强:执行目标方法之前,模拟开始事务...");
Object[] args=jp.getArgs();
if(args!=null&&args.length>0&&args[0].getClass()==String.class){
//改变第一个目标方法的第一个参数
args[0]="第一个被改变的参数";
}
Object rvt =jp.proceed(args);
System.out.println("around增强:执行目标方法之后,模拟结束事务...");
return rvt+"新添增的内容";
}
public void authority(JoinPoint jp) {
System.out.println("2,before增强:模拟执行权限检查");
System.out.println("2,before增强:被织入增强处理的目标方法为:"+jp.getSignature().getName());
System.out.println("2,before增强:目标方法的参数:"+Arrays.toString(jp.getArgs()));
System.out.println("2,before增强:被织入增强处理的对象为"+jp.getTarget());
}
public void log(JoinPoint jp,String rvt) {
System.out.println("afterreturning增强处理,获取目标方法返回值:"+rvt);
System.out.println("afterreturning增强处理:模拟记录日志功能...");
System.out.println("afterreturning增强处理:获取通知方法名:"+jp.getSignature().getName());
System.out.println("afterreturning增强处理:获取通知参数:"+Arrays.toString(jp.getArgs()));
System.out.println("afterreturning增强处理:获取被织入增强处理对象为:"+jp.getTarget());
}
public void release(JoinPoint jp) {
System.out.println("after增强处理,模拟方法结束后释放资源...");
System.out.println("after增强处理的通知方法:"+jp.getSignature().getName());
System.out.println("after增强处理的通知方法的参数:"+Arrays.toString(jp.getArgs()));
System.out.println("after增强处理的通知方法对象:"+jp.getTarget());
}
}
配置文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<aop:config>
<aop:aspect ref="aspectbean">
<aop:after pointcut="execution(* test.*.*(..))" method="release"/>
<aop:after-returning pointcut="execution(* test.*.*(..))" method="log" returning="rvt"/>
<aop:around pointcut="execution(* test.*.*(..))" method="processTx"/>
<aop:before pointcut="execution(* test.*.*(..))" method="authority"/>
</aop:aspect>
</aop:config>
<bean id="aspectbean" class="test.aspect1"/>
<bean id="person" class="test.person"></bean>
</beans>
运行文件:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ac {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
person p=ac.getBean("person",person.class);
p.action();
p.quming("路西");
}
}
主类文件(配置围绕它来配置,为它服务,获取它的参数值)
public class person {
public person() {
System.out.println("主类初始化");
}
public void action() {
System.out.println("人类开始活动");
}
public void quming(String name) {
System.out.println("人类为自己取得第一个名字"+name);
}
}
番外:一开始我以为我的jar包非常齐全的,但是后来发生这个错误
Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJAfterAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJExpressionPointcut] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/BCException
非常长的错误只是在说一件事:我缺少这个ar包:aspectjweaver
原来是我的aspectjweaver-1.6.2jar包版本不对,它需要老一点的版本aspectjweaver-1.5.3.jar
在我用了aspectjweaver-1.5.3版本的jar包,程序就正常运行了!
今天我要对此处加个补充:
今天我照常进行aop练习,发现在我的主类引用接口之后,运行类的ac不再是放进主类进行解析了而是引用接口类(相当于原始类)才可以对主类进行解析.
接口类
package one;
public interface person {
void language(String name);
}
主类实现接口
package one;
public class chinese implements person {
public chinese() {
System.out.println("你好我是中国人!");
}
public void language(String name) {
System.out.println(name);
}
}
切面类,配置我就不写出来了,上面都可以找到相同案例
运行类
package one;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ac {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
person p=(person) ac.getBean("ch");必须用接口进行多态,让原始类和主类共同在容器中加载才可进行解析!!若是缺少接口进行多态便会报这种错(请看图1.1)
p.language("林泽森");
}
}
这样程序就正常了!!!!!!
图1.1
我感觉全配置aop还是全注释aop还是零配置aop我都觉得各有优点
就我们今天所学的全配置而言,各种关系确实是非常清晰的.今天学习注释全配置aop例子到此为止