第三章AOP Java APIによる切断面の作成
前に補強を使用したとき,補強はターゲットクラスのすべての方法に織り込まれることが分かった.ターゲットクラスの特定の方法に強化を織り込む場合,ターゲット接続点の位置決めに接点を用いる必要がある.次に、カットポイントと強化によってカットを生成することができます.
3.4.1接点タイプ
静的メソッド接点:org.springframework.aop.support.StaticMethodMatcherPointcut
動的メソッド接点:org.springframework.aop.support.DynamicMethodMatcherPointcut
注記接点:org.springframework.aop.support.annotation.AnnotationMatchingPointcut
式接点:org.springframework.aop.support.ExpressionPointcut
プロセス接点:org.springframework.aop.support.ControlFlowPointcut
3.4.2静的方法で接面を一致させる
org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただし、UserDaoImplには2つのメソッド、saveメソッド、deleteメソッドがあります.次にsaveメソッドにフェースを構成します.
b、接面類継承S e c M t h o d MatcherPointcutAdvisor
c、構成
d、テスト
e、結果
3.4.3静的正規表現メソッド断面の構成
この方法は自分でうどん類を書く必要はありません.
org.springframework.aop.support.RegexpMethodPointcutAdvisorは正規表現法が一致する接面実装クラスである.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
b、配置
c、テスト
d、結果
一般的な正規表現規則
1、.*set.*すべてのクラスのsetを接頭辞とする方法を表します.如:com.abc.UserDao.setName().
2、com\.abc\.service\..*表示com.abc.service.すべてのクラスのすべてのメソッドをパッケージします.
Com.abc.service.a.User.setName()
Com.abc.service.UserService.save()
3、com\.abc\.service\..*Service\..*表示com.abc.サービスパッケージの下にサービスで終わるクラスのすべての方法.如:com.abc.service.UserService.save()
4、com\.abc\.service\..*Service\.save.+saveを接頭辞とするすべての方法を一致させ、save後に1つ以上の文字を持つ必要があります.如:com.abc.service.UserService.saveUser()
3.4.4ダイナミックカット
org.springframework.aop.support.D y n a m i c MethodMatcherPointcutクラスには静的接点検査の方法もあれば,動的接点検査の方法もある.ダイナミック接点チェックはパフォーマンスに大きな影響を及ぼすため、実行時にターゲットクラスの各メソッドを毎回チェックすることは避けなければなりません.
Spring動的接点をチェックするメカニズム:エージェントの作成時にターゲットクラスの各接続点に対して静的接点検査を行い、静的接点検査だけで接続点が一致していないことを知ることができ、実行期間中に動的検査を行わない.静的接点チェックが一致している場合は、実行期間中に動的メソッドチェックが行われます.
動的接面は、D y n a m i c MethodMatcherPointcut接点と組み合わせたD e f a u ltPointcutAdvisor接面クラスによって生成されます.主に接続点メソッドのパラメータです.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただ、UserDaoImplにはoutメソッドが1つ増えており、パラメータが付いています.
b、接点類継承DynamicMethodMatcherPointcut
c、構成
d、テスト
e、結果
3.4.5プロセススライス
1つのクラスのいずれかのメソッドがターゲットクラスの2つのメソッドを使用すると、プロセスフェースを使用して両方のメソッドに強化を積むことができます.
たとえば、UserServiceImplクラス(使用クラス)operateメソッドでUserDaoImpl(ターゲットクラス)を使用する2つのメソッドです.
プロセススライスは、ControlFlowPointcutを使用してDefaultPointcutAdvisorと結合して形成されます.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただし、UserDaoImplには2つのメソッド、saveメソッド、deleteメソッドがあります.次にsaveメソッドにフェースを構成します.
b、UserServiceImplクラス
c、構成
d、テスト
e、結果
3.4.6複合断面
前の例では、私たちが定義したうどんは1つの接点しかありません.接続点を決定するには、1つの切断面に複数の切断点、すなわち複数の条件が必要になる場合があります.複数の接点が1つの接点を構成し、このような接点は複合接点である.複合接点に補強された接面を加えて複合接面と呼ぶ.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
b.一般クラスにPointcutを取得する方法
c、構成
d、テスト
e、結果
3.4.7誘導切断面
a、使用3.3.6紹介強化の中身(インタフェースと強化類)
http://blog.csdn.net/p_3er/article/details/9239925
b、配置
c、テスト
d、結果
3.4.1接点タイプ
静的メソッド接点:org.springframework.aop.support.StaticMethodMatcherPointcut
動的メソッド接点:org.springframework.aop.support.DynamicMethodMatcherPointcut
注記接点:org.springframework.aop.support.annotation.AnnotationMatchingPointcut
式接点:org.springframework.aop.support.ExpressionPointcut
プロセス接点:org.springframework.aop.support.ControlFlowPointcut
3.4.2静的方法で接面を一致させる
org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただし、UserDaoImplには2つのメソッド、saveメソッド、deleteメソッドがあります.次にsaveメソッドにフェースを構成します.
b、接面類継承S e c M t h o d MatcherPointcutAdvisor
public class StaticAdvisor extends StaticMethodMatcherPointcutAdvisor {
/*
*
*/
public boolean matches(Method method, Class<?> clazz) {
return method.getName().equals("save");
}
/*
* StaticMethodMatcherPointcut getClassFilter()
*
*/
public ClassFilter getClassFilter() {
ClassFilter classFilter = new ClassFilter() {
public boolean matches(Class<?> clazz) {
return UserDaoImpl.class.isAssignableFrom(clazz);
}
};
return classFilter;
}
}
c、構成
<!-- Bean -->
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!-- 。p:advice-ref -->
<bean id="staticAdvisor" class="cn.framelife.spring.advisor.StaticAdvisor" p:advice-ref="userDaoBeforeAdvice"></bean>
<!--
p:interceptorNames ,
-->
<bean id="paramProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="staticAdvisor"
p:proxyTargetClass="true" />
<!-- -->
<bean id="userDaoProxy" parent="paramProxy" p:target-ref="userDao"></bean>
d、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserDao userDao = (UserDao) context.getBean("userDaoProxy");
//UserDaoImpl ,save ,delete
userDao.save();
System.out.println("----------");
userDao.delete();
e、結果
:save
...
----------
...
3.4.3静的正規表現メソッド断面の構成
この方法は自分でうどん類を書く必要はありません.
org.springframework.aop.support.RegexpMethodPointcutAdvisorは正規表現法が一致する接面実装クラスである.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
b、配置
<!-- Bean -->
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!--
Bean
patterns
, 。 : cn.framelife.spring.dao.impl.UserDaoImpl.delete()
<value>.*delete</value>
-->
<bean id="regexpAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:advice-ref="userDaoBeforeAdvice">
<property name="patterns">
<list>
<value>.*delete</value>
</list>
</property>
</bean>
<!--
-->
<bean id="regexpProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="regexpAdvisor"
p:target-ref="userDao"
p:proxyTargetClass="true" />
c、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserDao userDao = (UserDao) context.getBean("regexpProxy");
userDao.save();
System.out.println("----------");
userDao.delete();
d、結果
...
----------
:delete
...
一般的な正規表現規則
1、.*set.*すべてのクラスのsetを接頭辞とする方法を表します.如:com.abc.UserDao.setName().
2、com\.abc\.service\..*表示com.abc.service.すべてのクラスのすべてのメソッドをパッケージします.
Com.abc.service.a.User.setName()
Com.abc.service.UserService.save()
3、com\.abc\.service\..*Service\..*表示com.abc.サービスパッケージの下にサービスで終わるクラスのすべての方法.如:com.abc.service.UserService.save()
4、com\.abc\.service\..*Service\.save.+saveを接頭辞とするすべての方法を一致させ、save後に1つ以上の文字を持つ必要があります.如:com.abc.service.UserService.saveUser()
3.4.4ダイナミックカット
org.springframework.aop.support.D y n a m i c MethodMatcherPointcutクラスには静的接点検査の方法もあれば,動的接点検査の方法もある.ダイナミック接点チェックはパフォーマンスに大きな影響を及ぼすため、実行時にターゲットクラスの各メソッドを毎回チェックすることは避けなければなりません.
Spring動的接点をチェックするメカニズム:エージェントの作成時にターゲットクラスの各接続点に対して静的接点検査を行い、静的接点検査だけで接続点が一致していないことを知ることができ、実行期間中に動的検査を行わない.静的接点チェックが一致している場合は、実行期間中に動的メソッドチェックが行われます.
動的接面は、D y n a m i c MethodMatcherPointcut接点と組み合わせたD e f a u ltPointcutAdvisor接面クラスによって生成されます.主に接続点メソッドのパラメータです.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただ、UserDaoImplにはoutメソッドが1つ増えており、パラメータが付いています.
b、接点類継承DynamicMethodMatcherPointcut
public class DynamicPointcut extends DynamicMethodMatcherPointcut {
// list
private List<String> specialNames = new ArrayList<String>();
public DynamicPointcut(){
specialNames.add("aa");
specialNames.add("bb");
}
/*
*
*/
public ClassFilter getClassFilter() {
return new ClassFilter() {
@Override
public boolean matches(Class<?> targetClass) {
System.out.println(" getClassFilter :"+targetClass.getName());
return UserDaoImpl.class.isAssignableFrom(targetClass);
}
};
}
/*
*
*/
public boolean matches(Method method, Class<?> targetClass) {
System.out.println(" matches(method,targetClass) :"+targetClass.getName()+"--"+method.getName());
return method.getName().equals("out");
}
/*
*
*/
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
System.out.println(" matches(method,targetClass) :"+targetClass.getName()+"--"+method.getName()+" ");
String name = (String)args[0];
return specialNames.contains(name);
}
}
c、構成
<!-- Bean -->
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!-- -->
<bean id="dynamicAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<!-- -->
<property name="pointcut">
<bean class="cn.framelife.spring.pointcut.DynamicPointcut"></bean>
</property>
<!-- -->
<property name="advice" ref="userDaoBeforeAdvice"></property>
</bean>
<!--
-->
<bean id="dynamicProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="dynamicAdvisor"
p:target-ref="userDao"
p:proxyTargetClass="true" />
d、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserDao userDao = (UserDao) context.getBean("dynamicProxy");
//UserDaoImpl out , 。
System.out.println("----------");
userDao.save();
System.out.println("----------");
userDao.out("aa");
System.out.println("----------");
userDao.out("1111");
System.out.println("----------");
e、結果
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--out
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--save
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--delete
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--clone
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--toString
----------
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--save
...
----------
getClassFilter :cn.framelife.spring.dao.impl.UserDaoImpl
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--out
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--out
:out
out :aa
----------
matches(method,targetClass) :cn.framelife.spring.dao.impl.UserDaoImpl--out
out :1111
----------
3.4.5プロセススライス
1つのクラスのいずれかのメソッドがターゲットクラスの2つのメソッドを使用すると、プロセスフェースを使用して両方のメソッドに強化を積むことができます.
たとえば、UserServiceImplクラス(使用クラス)operateメソッドでUserDaoImpl(ターゲットクラス)を使用する2つのメソッドです.
プロセススライスは、ControlFlowPointcutを使用してDefaultPointcutAdvisorと結合して形成されます.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
ただし、UserDaoImplには2つのメソッド、saveメソッド、deleteメソッドがあります.次にsaveメソッドにフェースを構成します.
b、UserServiceImplクラス
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser() {
userDao.save();
}
@Override
public void operate() {
// userDao
userDao.delete();
userDao.save();
}
}
c、構成
<!-- Bean -->
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!-- -->
<bean id="controlFlowPointcut" class="org.springframework.aop.support.ControlFlowPointcut">
<!-- -->
<constructor-arg type="java.lang.Class" value="cn.framelife.spring.service.impl.UserServiceImpl"></constructor-arg>
<!-- -->
<constructor-arg type="java.lang.String" value="operate"></constructor-arg>
</bean>
<!-- -->
<bean id="controlFlowAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor"
p:pointcut-ref="controlFlowPointcut"
p:advice-ref="userDaoBeforeAdvice"/>
<!--
-->
<bean id="controlFlowProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="controlFlowAdvisor"
p:target-ref="userDao"
p:proxyTargetClass="true" />
<!-- Bean Spring -->
<bean id="userService" class="cn.framelife.spring.service.impl.UserServiceImpl">
<property name="userDao" ref="controlFlowProxy"></property>
</bean>
d、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService userService = (UserService) context.getBean("userService");
userService.operate();
System.out.println("----------------");
userService.addUser();
e、結果
:delete
...
:save
...
----------------
...
3.4.6複合断面
前の例では、私たちが定義したうどんは1つの接点しかありません.接続点を決定するには、1つの切断面に複数の切断点、すなわち複数の条件が必要になる場合があります.複数の接点が1つの接点を構成し、このような接点は複合接点である.複合接点に補強された接面を加えて複合接面と呼ぶ.
a、強化クラス
ここで使用するのは3.3です.2の前面拡張:
http://blog.csdn.net/p_3er/article/details/9239925
b.一般クラスにPointcutを取得する方法
public class MyPointcut {
// Pointcut get
public Pointcut getMyComposablePointcut(){
//
ComposablePointcut cp = new ComposablePointcut();
// ( : 、 ) 3.4.5 UserServiceImpl
Pointcut pt1 = new ControlFlowPointcut(UserServiceImpl.class,"operate");
//
Pointcut pt2 = new StaticMethodMatcherPointcut() {
public boolean matches(Method method, Class<?> clazz) {
return UserDaoImpl.class.isAssignableFrom(clazz)&&method.getName().equals("delete");
}
};
// .
return cp.intersection(pt1).intersection(pt2);
}
}
c、構成
<!-- Bean -->
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!-- -->
<bean id="myPoincut" class="cn.framelife.spring.pointcut.MyPointcut"></bean>
<!--
p:pointcut #{ myPoincut.myComposablePointcut} MyPointcut getMyComposablePointcut
-->
<bean id="composableAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor"
p:pointcut="#{ myPoincut.myComposablePointcut}"
p:advice-ref="userDaoBeforeAdvice"/>
<!--
-->
<bean id="composableProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="composableAdvisor"
p:target-ref="userDao"
p:proxyTargetClass="true" />
<!-- Bean Spring -->
<bean id="userService" class="cn.framelife.spring.service.impl.UserServiceImpl">
<property name="userDao" ref="composableProxy"></property>
</bean>
d、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService userService = (UserService) context.getBean("userService");
userService.operate();
e、結果
:delete
...
...
3.4.7誘導切断面
a、使用3.3.6紹介強化の中身(インタフェースと強化類)
http://blog.csdn.net/p_3er/article/details/9239925
b、配置
<!-- Bean -->
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>
<!--
constructor-arg
-->
<bean id="introductionAdvisor"
class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg>
<bean class="cn.framelife.spring.advice.IntroductionAdvice"></bean>
</constructor-arg>
</bean>
<!--
-->
<bean id="incluctionProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="introductionAdvisor"
p:target-ref="userDao"
p:proxyTargetClass="true" />
c、テスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserDao userDao = (UserDao) context.getBean("aProxy");
userDao.save();
System.out.println("-------------");
AInterface a = (AInterface)userDao;
a.say();
System.out.println("-------------");
userDao.save();
d、結果
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
...
-------------
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
say
UserDao
-------------
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
...