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;
}
}