春は-Spring07-AOPの通知学びます

Spring07-AOP

セクション
断面ビジネスロジックを指します。トランザクション処理など、ログ処理部として理解することができます。一般的に使用されるセクション
の通知やコンサルタントを持っています。これは、実際には主要なビジネスロジックの拡張の一種です。

通知(アドバイス)
通知部は、単純な織りの実装は(織りがここで行われていること)が完了しています。
通知は、ターゲットメソッドの実行、または前に実行されたオブジェクトコードを切断する時にコードポイントに拡張機能を定義し
た後などに実行。別の通知タイプ、異なるカットイン時間。

常用的通知分类
前置通知 MethodBeforeAdvice
后置通知 AfterReturningAdvice
环绕通知MethodInterceptor
异常处理通知ThrowsAdvice

春AOPを実現します

Spring对AOP的实现
基于Schema-based方式
AspectJ的实现方式
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については、インターフェースなぜ利用価値の背後にありますか?

  1. proxyInterfaces(底パスクラス値型は[])=「」タグ値の配列、のみ値、値の複数によって提供されている
    底。
    java proxyInterfaces-ProxyFactoryBean.setProxyInterfaces(Class[] proxyInterfaces) //.xml文件中给不了class,只能给全限定名
  2. ターゲット(渡された値型基礎となるオブジェクトのターゲット)
    下:
    java target-Advised.setTarget(Object object)//Object所以使用ref传对象
  3. 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);
		
		
	}	

}

リリース8元の記事 ウォンの賞賛0 ビュー166

おすすめ

転載: blog.csdn.net/Fu_si/article/details/104524924