AOP
: 面向切面編程 , 其中有 橫切面
, 連接點
{前置通知,環繞通知,後置通知}該例中用到的是 環繞通知, 切入點
(指定需要代理的方法)。
其中用到的是Spring 1.2 版本。
還是以Person為例:
IPerson 介面(可理解為業務介面):
public
interface
IPerson {
public void sleep();
public void walk();
}
IPerson的實作類別(可理解為業務實作類別):
public
class
PersonImp implements
IPerson{
public
void sleep() {
System.out
.println("sleep..."); //具體業務操作,比如:向資料庫插入資料
}
public
void walk() {
System.out
.println("walk..."); //具體業務操作,比如:向資料庫插入資料
}
}
定義連接點(
前置通知 || 環繞通知
||
後置通知}這裡用的是 環繞通知
,如果使用 前置通知,或 後置通知 比這個簡單):
public
class
AroundNote implements
MethodInterceptor{
public
Object invoke(MethodInvocation arg0) throws
Throwable {
System.out
.println("befor"); //如:服務代碼,例如 事務開啟
Object o = arg0.proceed();
System.out
.println("after"); //如:服務代碼,例如 事務提交,復原
return
o;
}
}
測試類別:
public
class
ProxyTest {
public
static
void main(String[] args) {
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml"); //開啟Spring容器,載入配置
IPerson person = (IPerson) ac.getBean("personImp"); //擷取目標對象(業務類)
person.sleep();
person.walk();
}
}
/* 以上分析: 當執行到sleep時, 先去執行 連接點 裡的 System.out
.println("befor");
這個代碼, 然後 執行 sleep 最後執行 System.out
.println("after");
如果 sleep 裡的是 hibernate 對資料庫的操作, 那麼 System.out
.println("befor");
這句代碼, 改成 事務的開啟,System.out
.println("after");
這個代碼 改為 事務的提交, 那麼 所有的事務都可以用這種方式完成, 事務和業務就分離了。 */
輸出結果:
befor // 如果這裡是 事務 開啟
sleep... // 這裡對資料庫操作
after // 如果這裡是 事務 提交 或 復原
befor
walk...
after
Spring的配置:
<?xml
version
="1.0
" encoding
="UTF-8
"?>
<beans
xmlns
="http://www.springframework.org/schema/beans
"
xmlns
:xsi
="http://www.w3.org/2001/XMLSchema-instance
"
xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
">
<!-- 目標對象(業務類) -->
<bean
id
="personImp
" class
="org.lc.autoproxy.PersonImp
"></bean>
<!-- 環繞通知 AOP {JointPoint(連接點)} -->
<bean
id
="aroundnote
" class
="org.lc.autoproxy.AroundNote
"></bean>
<bean
class
="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreato
r
">
<!-- name為BeanNameAutoProxyCreator中的setBeanNames方法,以下相同 -->
<property
name
="beanNames
">
<value>
personImp</value>
</property>
<!-- 指定連接點 -->
<property
name
="interceptorNames
">
<list>
<value>
aroundnote</value>
</list>
</property>
</bean>
</beans>