Spring编程<三>
AOP切面技术——版本1
AOP的公式:
**AOP 的一个公式 : 切面 = 切点+通知
Aspect = Pointcut(拦截哪个/些 函数) + advice(在哪个时间点拦截 before,after,around)**
演示代码:
被代理的对象:
JAVA实验代码:
// 纯Java代码方式实现AOP
@Test
public void t1() {
// 1、被代理对象---原型对象
Person p = new Person();
// 2、实现代理的类
// ProxyFactory f= new ProxyFactory();低版本 不建议使用
// Bean的代理工厂
ProxyFactoryBean factory = new ProxyFactoryBean();
// 3、给代理工厂设置被代理的对象(代理的目标)
factory.setTarget(p);
// 切面 = 切点+通知
// 4、定义切点
JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
// 5、为切点设置正则表达式
cut.setPattern(".*run.*");//.*代表所有
// 6、定义通知
Advice advie = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("前面拦截...");
Object returnValue = invocation.proceed();// 放行
System.out.println("后面拦截...");
return returnValue;
}
};
// 7、声明切面 Advisor = cut + advice
Advisor advisor = new DefaultPointcutAdvisor(cut, advie);
// 8、把切面设置到代理工厂中
factory.addAdvisor(advisor);
// 9、从代理工厂中获取代理后的对象
Person p2 = (Person) factory.getObject();
// 10、用代理后的对象执行方法,如果符合规则,就拦截
p2.run();
}
指定拦截前还是后:
@Test
public void t2() {
ProxyFactoryBean factory = new ProxyFactoryBean();
factory.setTarget(new Person());
// 切面 = 切点+通知
JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
cut.setPatterns(new String[] { ".*hello.*", ".*run.*" });
// 注意 Advice都是用的AOP包的接口
Advice before = new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("before拦截...");
}
};
// 声明切面 1 Advisor = cut + advice
Advisor advisor1 = new DefaultPointcutAdvisor(cut, before);
// 方法执行完毕
Advice after = new AfterReturningAdvice() {
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
System.out.println("after拦截(方法执行完毕)...");
}
};
// 声明切面2 Advisor = cut + advice
Advisor advisor2 = new DefaultPointcutAdvisor(cut, after);
// 8、把切面设置到代理工厂中
factory.addAdvisor(advisor1);
factory.addAdvisor(advisor2);
// 9、从代理工厂中获取代理后的对象
Person p2 = (Person) factory.getObject();
// 10、用代理后的对象执行方法,如果符合规则,就拦截
p2.run();
p2.hello();
}
演示结果:
用XML形式完成:
配置文件v1.xml
<bean id="p" class="cn.hncu.v1.Person">
</bean>
<!-- class:这里是用alt+/代码补全的包 ,如果无法补全,请参考下面-->
<bean id="cut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*run.*"></property>
</bean>
<bean id="aroundAdvice" class="cn.hncu.v1.AroundAdvice">
</bean>
<!-- new 一个对象,这里就是一个bean -->
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="cut"></property>
<property name="advice" ref="advisor"></property>
</bean>
<bean id="personProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="p"></property>
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>
手动添加 schema文件,方法如下:
版本可以自行改变,以下是2.5
windwos->preferences->myeclipse->files and editors->xml->xmlcatalog
点击“add”,在出的窗口中的keyttype中选择url,在locationspring-beans-2.5.xsd中选择”file system”,然后spring解压目录的dist/resources目录中选择spring-beans-2.5.xsd,回到设置窗口的时候不要急着关闭窗口,应把窗口中的key type改为schemalocation,key改为http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
演示代码:
@Test
public void t1() {
ApplicationContext ctx= new ClassPathXmlApplicationContext("cn/hncu/v1/v1.xml");
Person p =ctx.getBean("personProxyFactory", Person.class);
p.run();//拦
p.hello();//不拦
}
写一个Advice实现MethodInterceptor
在自己的Advice中写拦截,通过配置文件控制。
public class AroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("前面拦截...");
Object returnValue = invocation.proceed();// 放行
System.out.println("后面拦截...");
return returnValue;
}
}