Springのaop浅析
13086 ワード
spring aopプログラミング全体について個人的に理解する
つまり、aspectでpointcutを使用してブロックするjoinpointを定義し、weavingの過程でtargetオブジェクトにaspectで定義したadviceを付加する行為です.
まずspring実装エージェントの2つの方法を見てみましょう:jdkダイナミックエージェントとcglibエージェント(説明が必要な場所コードに説明があります)
テストクラスSpringTestProxy.java
コンソール出力:
ツールクラス
ProxyObjectInstance.java
springの2つのエージェント方式の結果は一致しており、ターゲットオブジェクトにインタフェースがある場合、jdkを使用する動的エージェントは、ターゲットオブジェクトにインタフェースがない場合、cglibエージェントを使用して実現される.
次にspringのaopプログラミングの2つの方式の注釈とxmlファイルの方式を見てみましょう
まず注釈の仕方を見てみましょう
テストコード:
SpringTestAspectJ.java
プロファイルアプリケーションContext.xml
切断ファイルjava
ターゲットオブジェクトjava
テストメソッドの実行
コンソール出力:
以上,注釈を用いてspring sopを実現する.
プロファイルアプリケーションContextを変更する.JAvaは以下の通りです
純java類AspectXml.java
テストメソッドコンソールの出力を実行します.
総じてspringのaop
個人的には事務管理の1つを使うのは本当にとても便利だと感じて、多くのコードを簡略化しましたもちろん私のレベルは限られていて、もっと多くの機能があるかもしれません.私はまだ上のテストの例が比較的に簡単に詳しく書いてあることに気づいていません.springの公式ドキュメントには記録学習の足どりを説明して努力し続けています.
追加:pointcut式のいくつかの解釈
All parts except the returning type pattern (ret-type-pattern in the snippet above), name pattern, and parameters pattern are optional. The returning type pattern determines what the return type of the method must be in order for a join point to be matched. Most frequently you will use
例
つまり、aspectでpointcutを使用してブロックするjoinpointを定義し、weavingの過程でtargetオブジェクトにaspectで定義したadviceを付加する行為です.
まずspring実装エージェントの2つの方法を見てみましょう:jdkダイナミックエージェントとcglibエージェント(説明が必要な場所コードに説明があります)
テストクラスSpringTestProxy.java
package com.undergrowth.test;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.weaver.NewConstructorTypeMunger;
import org.junit.Test;
import com.undergrowth.utils.ProxyObjectInstance;
/*
* Spring Proxy
* 1.jdk dynamic proxy(jdk )
* 2.cglib proxy( jar cglib )
*
*
*/
public class SpringTestProxy {
@Test
public void test() {
ProxyObjectInstance proxyObjectInstance=new ProxyObjectInstance();
List arrayList=(List) proxyObjectInstance.createJdkProxyObject(new ArrayList());
System.out.println(arrayList.add(3));
arrayList=(List) proxyObjectInstance.createCglibObject(new ArrayList());
System.out.println(arrayList.add(3));
}
}
コンソール出力:
true
cglib
cglib
true
ツールクラス
ProxyObjectInstance.java
package com.undergrowth.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/*
* jdk cglib
*/
public class ProxyObjectInstance implements InvocationHandler,MethodInterceptor{
private Object target;
// jdk
// InvocationHandler (invoke )
public Object createJdkProxyObject(Object targetObject)
{
this.target=targetObject;
Class targetClass=this.target.getClass();
return Proxy.newProxyInstance(targetClass.getClassLoader(),targetClass.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//
System.out.println(" ");
//
Object returnValue=method.invoke(target, args);
System.out.println(" ");
return returnValue;
}
// cglib
// final MethodInterceptor
// (intercept )
public Object createCglibObject(Object targetObject)
{
this.target=targetObject;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] args,
MethodProxy method) throws Throwable {
//
System.out.println(" cglib ");
//
Object returnValue=method.invoke(target, args);
System.out.println(" cglib ");
return returnValue;
}
}
springの2つのエージェント方式の結果は一致しており、ターゲットオブジェクトにインタフェースがある場合、jdkを使用する動的エージェントは、ターゲットオブジェクトにインタフェースがない場合、cglibエージェントを使用して実現される.
次にspringのaopプログラミングの2つの方式の注釈とxmlファイルの方式を見てみましょう
まず注釈の仕方を見てみましょう
テストコード:
SpringTestAspectJ.java
package com.undergrowth.test;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.undergrowth.aspect.test.bean.TargetObject;
/*
* aspectj spring aop
*1. spring aspectj
*2. @Aspect
*
* xml
* xml pojo aspect
*
*
*
**
* Weaving( )---linking aspects with other application types or objects
* to create an advised object.
*
* spring , @Transactional ,spring aop
* 、 、
*
*
* spring aop
* aspect pointcut joinpoint, weaving ,
* target aspect advice
*
*/
public class SpringTestAspectJ {
private static AbstractApplicationContext aac;
@BeforeClass
public static void beforeClass()
{
aac=new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test()
{
TargetObject targetObject= (TargetObject) aac.getBean("targetObject");
targetObject.say("spring aop annotation ");
}
}
プロファイルアプリケーションContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- enable Spring support for configuring Spring AOP based on @AspectJ aspects,
and autoproxying beans based on whether or not they are advised by those aspects.
aspectj java
-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="aspectDefinition" class="com.undergrowth.aspect.AspectDefinition"></bean>
<!-- xml java com.undergrowth.aspect.AspectXml aspect
-->
<!-- <bean id="aspectXml" class="com.undergrowth.aspect.AspectXml"></bean>
<aop:config>
<aop:aspect ref="aspectXml">
<aop:pointcut expression="execution(* com.undergrowth.aspect.test.bean..*.*(..))" id="pointcut"/>
<aop:before method="beforeAdvice" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturn" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config> -->
<bean id="targetObject" class="com.undergrowth.aspect.test.bean.TargetObject"></bean>
</beans>
切断ファイルjava
package com.undergrowth.aspect;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
// java
@Aspect
public class AspectDefinition {
// --
@Pointcut("execution(* com.undergrowth.aspect.test.bean..*.*(..))")
private void interceptorDefini(){}
//
@Before("interceptorDefini()")
public void beforeAdvice()
{
System.out.println(" ");
}
//
@AfterReturning("interceptorDefini()")
public void afterReturn()
{
System.out.println(" ");
}
}
ターゲットオブジェクトjava
package com.undergrowth.aspect.test.bean;
/*
*
*/
public class TargetObject {
public void say(String sayWhat)
{
System.out.println(" :"+sayWhat);
}
}
テストメソッドの実行
コンソール出力:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
:spring aop annotation
以上,注釈を用いてspring sopを実現する.
プロファイルアプリケーションContextを変更する.JAvaは以下の通りです
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- enable Spring support for configuring Spring AOP based on @AspectJ aspects,
and autoproxying beans based on whether or not they are advised by those aspects.
aspectj java
-->
<!-- <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="aspectDefinition" class="com.undergrowth.aspect.AspectDefinition"></bean> -->
<!-- xml java com.undergrowth.aspect.AspectXml aspect
-->
<bean id="aspectXml" class="com.undergrowth.aspect.AspectXml"></bean>
<aop:config>
<aop:aspect ref="aspectXml">
<aop:pointcut expression="execution(* com.undergrowth.aspect.test.bean..*.*(..))" id="pointcut"/>
<aop:before method="beforeAdvice" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturn" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<bean id="targetObject" class="com.undergrowth.aspect.test.bean.TargetObject"></bean>
</beans>
純java類AspectXml.java
package com.undergrowth.aspect;
/*
* xml aspect
*/
public class AspectXml {
public void beforeAdvice()
{
System.out.println(" xml ");
}
public void afterReturn()
{
System.out.println(" xml ");
}
}
テストメソッドコンソールの出力を実行します.
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
xml
:spring aop annotation
xml
総じてspringのaop
個人的には事務管理の1つを使うのは本当にとても便利だと感じて、多くのコードを簡略化しましたもちろん私のレベルは限られていて、もっと多くの機能があるかもしれません.私はまだ上のテストの例が比較的に簡単に詳しく書いてあることに気づいていません.springの公式ドキュメントには記録学習の足どりを説明して努力し続けています.
追加:pointcut式のいくつかの解釈
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
All parts except the returning type pattern (ret-type-pattern in the snippet above), name pattern, and parameters pattern are optional. The returning type pattern determines what the return type of the method must be in order for a join point to be matched. Most frequently you will use
*
as the returning type pattern, which matches any return type. A fully-qualified type name will match only when the method returns the given type. The name pattern matches the method name. You can use the *
wildcard as all or part of a name pattern. The parameters pattern is slightly more complex: ()
matches a method that takes no parameters, whereas (..)
matches any number of parameters (zero or more). The pattern (*)
matches a method taking one parameter of any type, (*,String)
matches a method taking two parameters, the first can be of any type, the second must be a String. Consult the Language Semantics section of the AspectJ Programming Guide for more information. 例
the execution of any method defined in the service package or a sub-package:
execution(* com.xyz.service..*.*(..))