Spring07-AOP
セクション
断面ビジネスロジックを指します。トランザクション処理など、ログ処理部として理解することができます。一般的に使用されるセクション
の通知やコンサルタントを持っています。これは、実際には主要なビジネスロジックの拡張の一種です。
通知(アドバイス)
通知部は、単純な織りの実装は(織りがここで行われていること)が完了しています。
通知は、ターゲットメソッドの実行、または前に実行されたオブジェクトコードを切断する時にコードポイントに拡張機能を定義し
た後などに実行。別の通知タイプ、異なるカットイン時間。
春AOPを実現します
1.通知の使用
- カスタム通知クラス
//切面:前置通知
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
/**
* method:目标方法
* args:目标方法参数列表
* target:目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置方法的before()方法执行!");
}
}
//切面:后置通知
public class MyAfterReturningAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置通知的afterReturning()方法执行!returnValue: " + returnValue);
if (returnValue != null) {
System.out.println(((String)returnValue).toUpperCase());
}
}
}
//切面:环绕通知
public class MyMethodInterceptor implements MethodInterceptor {
/**
* invocation: 方法调用器
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕通知:目标方法执行之前!");
//调用执行目标方法
Object result = invocation.proceed();
if (result != null) {
result = ((String)result).toUpperCase();
}
System.out.println("环绕通知:目标方法执行之后!");
return result;
}
}
//切面:异常通知(发生异常,目标方法不再执行)
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Exception ex) {
System.out.println("异常通知执行!" + ex);
}
}
- ターゲットクラスの定義
package com.caorui.service;
public interface SomeService {
void doSome();
String doOther();
}
package com.caorui.service.impl;
import com.caorui.service.SomeService;
public class SomeServiceImpl implements SomeService {
public SomeServiceImpl() {
System.out.println("SomeServiceImpl.SomeServiceImpl()");
}
@Override
public void doSome() {
// System.out.println("SomeServiceImpl.doSome()");
System.out.println("SomeServiceImpl.doSome()" + 1/0);
}
@Override
public String doOther() {
System.out.println("SomeServiceImpl.doOther()");
return "love";
}
}
- サインターゲットクラス、通知セクション、登録済みのエージェントクラスオブジェクト豆工場ProxyFactoryBeanに登録
<?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.xsd">
<!-- 注册目标类 -->
<!-- bean的定义:以下配置相当于SomeService service = new SomeServiceImpl(); id相当于service这个引用 -->
<bean id="someServiceImpl" class="com.caorui.service.impl.SomeServiceImpl"></bean>
<!-- 注册切面,前置通知 -->
<bean id="myMethodBeforeAdvice" class="com.caorui.aspects.MyMethodBeforeAdvice"></bean>
<!-- 注册切面,后置通知 -->
<bean id="myAfterReturningAdvice" class="com.caorui.aspects.MyAfterReturningAdvice"></bean>
<!-- 注册切面,环绕通知 -->
<bean id="myMethodInterceptor" class="com.caorui.aspects.MyMethodInterceptor"></bean>
<!-- 注册切面,异常通知 -->
<bean id="myThrowsAdvice" class="com.caorui.aspects.MyThrowsAdvice"></bean>
<!-- 注册代理 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 指定目标对象 -->
<property name="target" ref="someServiceImpl"></property>
<!-- 指定目标类实现的所有接口 -->
<property name="interfaces" value="com.caorui.service.SomeService"></property>
<!-- 指定切面 -->
<property name="interceptorNames" value="myThrowsAdvice"></property>
</bean>
</beans>
注:interceptorNamesについては、インターフェースなぜ利用価値の背後にありますか?
- proxyInterfaces(底パスクラス値型は[])=「」タグ値の配列、のみ値、値の複数によって提供されている
底。
java proxyInterfaces-ProxyFactoryBean.setProxyInterfaces(Class[] proxyInterfaces) //.xml文件中给不了class,只能给全限定名
- ターゲット(渡された値型基礎となるオブジェクトのターゲット)
下:
java target-Advised.setTarget(Object object)//Object所以使用ref传对象
- interceptorNames:クラス通知セクション名は、値=「」場合は、文字列[]は、値を設定入力
底:
java interceptorNames-ProxyFactoryBean.setInterceptorNames(String[] interceptorNames)
複数の値と値を使用して、だからinterceptorNames値が、戻され、プラスアレイまたはリスト。
- クライアントアクセス、ダイナミックプロキシオブジェクト
package com.caorui.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import com.caorui.service.SomeService;
import com.caorui.service.impl.SomeServiceImpl;
public class SomeTest {
@Test
public void testSome01() {
//创建容器对象,ApplicationContext初始化时,所有容器中beans创建完毕
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeService service = ac.getBean("proxyFactoryBean", SomeService.class);
service.doSome();
String result = service.doOther();
System.out.println(result);
}
}