第三章AOP Java APIによる作成強化


3.3.1拡張タイプ
前置き強化:org.springframework.aop.MethodBeforeAdvice
後置強化:org.springframework.aop.AfterReturningAdvice
周回強化:org.aopalliance.intercept.MethodInterceptor
異常放出の強化:org.springframework.aop.ThrowsAdvice
導入の強化:org.springframework.aop.support.D e l e gatingIntroductionInterceptor
3.3.2先行強化
接続ポイントメソッドが実行される前に実行される内容です.
たとえば、UserDaoImplのsave()メソッドを実行する前に、いくつかの内容を実行します.
a、UserDaoとUserDaoImpl:
[java]  view plain copy print ?
public interface UserDao {    
    public void save();    
}    
[html]  view plain copy print ?
public class UserDaoImpl implements UserDao {    
    public void save() {    
        System.out.println(「ユーザーを保存...」);    
    }    
}    

b、強化クラスの実現を作成する
MethodBeforeAdviceインタフェース
public class UserDaoBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object object)
			throws Throwable {
		System.out.println("      ");
	}
}

c、構成
<!--       spring   -->
	<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>

	<!--       spring   -->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<!-- 
		      
		p:target-ref     
		p:proxyInterfaces          ,          
		p:interceptorNames      Bean,     , ","   
	-->
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice"
		p:target-ref="userDao"
	 />

d、mainメソッドでのテスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//       userDao  
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、結果
      
    ...

3.3.3バックグラウンドの強化
接続ポイントメソッドの実行後に実行される内容です.
a、UserDaoとUserDaoImpl:
[java]  view plain copy print ?
public interface UserDao {    
    public void save();    
}    
[html]  view plain copy print ?
public class UserDaoImpl implements UserDao {    
    public void save() {    
        System.out.println(「ユーザーを保存...」);    
    }    
}    

b、強化クラスの実現を作成する
AfterReturningAdviceインタフェース
public class UserDaoAfterAdvice implements AfterReturningAdvice {
	@Override
	public void afterReturning(Object object, Method method, Object[] args,
			Object arg3) throws Throwable {
		System.out.println("      ");
	}
}

c、構成
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
	<bean id="userDaoAfterAdvice" class="cn.framelife.spring.advice.UserDaoAfterAdvice"></bean>

	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice,userDaoAfterAdvice"
		p:target-ref="userDao"
	 />

d、mainメソッドでのテスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//       userDao  
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、結果
    ...
      

3.3.4オービット強化
オービット増強はstruts 2のAOPと類似している.
a、UserDaoとUserDaoImpl:
[java]  view plain copy print ?
public interface UserDao {    
    public void save();    
}    
[html]  view plain copy print ?
public class UserDaoImpl implements UserDao {    
    public void save() {    
        System.out.println(「ユーザーを保存...」);    
    }    
}    

b、強化クラスの実現を作成する
MethodInterceptorインタフェース
public class UserDaoSurroundAdvice implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("          ...");
		Object object = invocation.proceed();
		System.out.println("          ...");
		return object;
	}

}

c、構成
<bean id="userDaoSurroundAdvice" class="cn.framelife.spring.advice.UserDaoSurroundAdvice"></bean>
	
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames=" userDaoSurroundAdvice"
		p:target-ref="userDao"
	 />

d、mainメソッドでのテスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//       userDao  
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、結果
          ...
    ...
          ...

3.3.5異常放出増強
メソッドに異常が発生した後に実行されるコードです.
a、UserDaoとUserDaoImpl:
[java]  view plain copy print ?
public interface UserDao {    
    public void save();    
}    
public class UserDaoImpl implements UserDao {    
     public void save() {    
         System.out.println("    ...");    
         //               
          throw new RuntimeException("     ...");

    }    
}  

b、強化クラスの実現を作成する
ThrowsAdviceインタフェース
public class UserDaoThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(Method method,Object[] args,Object taglet,Exception ex)throws Throwable{
		System.out.println("        ");
		System.out.println(method.getName());
		System.out.println(ex.getMessage());
	}
}

c、構成
<bean id="userDaoThrowAdvice" class="cn.framelife.spring.advice.UserDaoThrowsAdvice"></bean>

<!--
	 p:proxyTargetClass="false"
	          ,       ,     true
-->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoThrowAdvice"
		p:target-ref="userDao"
		p:proxyTargetClass="false"
	 />

d、mainメソッドでのテスト
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//       userDao  
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、結果
    ...
Exception in thread "main" java.lang.RuntimeException:      ...
	at cn.framelife.spring.dao.impl.UserDaoImpl.save(UserDaoImpl.java:12)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$FastClassByCGLIB$$18bd6dee.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)        
save
     ...

	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$EnhancerByCGLIB$$5bbe38b0.save(<generated>)
	at cn.framelife.spring.test.Test.main(Test.java:17)

3.3.6導入強化
     導入強化は、ターゲットクラスに新しいメソッドと属性を作成します.導入強化の接続点はクラスレベルであり、メソッドレベルではありません.導入強化により、ターゲットクラスにインタフェースの実装を追加できます.つまり、元のターゲットクラスはインタフェースを実装していません.導入強化により、ターゲットクラスにインタフェースを実装するエージェントを作成できます.
a、UserDaoとUserDaoImpl:
[java]  view plain copy print ?
public interface UserDao {    
    public void save();    
}    
[html]  view plain copy print ?
public class UserDaoImpl implements UserDao {    
    public void save() {    
        System.out.println(「ユーザーを保存...」);    
    }    
}    

b、新しいインタフェース
AInterface
public interface AInterface {
	public void say();
}

c、強化クラス継承
DelegatingIntroductionInterceptor実装
AInterface
public class IntroductionAdvice extends DelegatingIntroductionInterceptor implements AInterface {
	/*
	 *   AInterface    
	 */
	public void say() {
		System.out.println("UserDao   ");
	}

	/*
	 *   DelegatingIntroductionInterceptor invoke  
	 */
	public Object invoke(MethodInvocation mi) throws Throwable {
		System.out.println("       ");
		System.out.println(mi.getClass().getName());
		System.out.println(mi.getMethod().getName());
		Object object = super.invoke(mi);
		System.out.println("       ");
		return object;
	}	
}

d、構成
<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="introductionAdvice" class="cn.framelife.spring.advice.IntroductionAdvice"></bean>
	<!-- 
		     
		p:proxyTargetClass="true"                   ,      true。
			      p:proxyInterfaces      
		p:interfaces           
	 -->
	<bean id="aProxy" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interfaces="cn.framelife.spring.dao.AInterface" 
		p:interceptorNames="introductionAdvice"
		p:target-ref="userDao" 
		p:proxyTargetClass="true" />

e、mainメソッドでのテスト
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();

f、結果
       
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
    ...
       
-------------
       
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
say
UserDao   
       
-------------
       
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
    ...