English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

пример Spring AOP

дает Старая реализация aop Spring 1.2 (базируется на dtd) пример реализации.

Хотя это поддерживается в Spring 3, использование advice будет рассмотрено на следующей странице, где мы будем изучать использование Spring aop с AspectJ.

в старой реализации aop Spring 1.2 поддерживались 4 типа Advice.

Before Adviceвыполняется до вызова фактического метода. After Adviceвыполняется после вызова фактического метода. Если метод возвращает значение, выполняется после значения возвращения. Around Adviceвыполняется до и после вызова фактического метода. Throws AdviceЕсли фактический метод вызывает исключение, выполняется это Advice.

Внимание: Чтобы понять основные концепции Spring AOP, перейдите на предыдущую страницу.

иерархия Advice

Давайте разберемся с иерархией Advice на следующем рисунке:

все это интерфейсы в aop.

MethodBeforeAdvice интерфейс расширяет BeforeAdvice интерфейс.

AfterReturningAdvice интерфейс расширяет AfterAdvice интерфейс.

ThrowsAdvice 接口扩展 AfterAdvice интерфейс.

MethodInterceptor 接口扩展 интерфейс расширения интерфейс. Он используется вокруг Advice.

1. Пример MethodBeforeAdvice

Создать класс, содержащий фактическую бизнес-логику.

Файл: A.java

package com.w3codebox;
public class A {
public void m(){System.out.println("реальный бизнес-логик");}
}

Теперь создайте класс консультанта, реализующий интерфейс MethodBeforeAdvice.

Файл: BeforeAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvisor implements MethodBeforeAdvice{
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("дополнительная проблема перед фактической логикой");
	}
}

В xml файле создайте три bean, один для класса A, второй для класса Advisor, третий для ProxyFactoryBean класс.

Файл: applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.BeforeAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

Понимание класса ProxyFactoryBean:

ProxyFactoryBean Класс предоставляется Spring Famework. Он содержит два свойства target и interceptorNames. Экземпляр класса A будет считаться объектом цели, а экземпляр класса顾问 будет считаться拦截ором. Вам нужно передать объект顾问 в виде объекта списка, как указано в предоставленном xml файле.

Составление класса ProxyFactoryBean так:

public class ProxyFactoryBean{
private Object target;
private List interceptorNames;
// getter и setter
}

Теперь, давайте вызовем реальный метод.

Файл: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	A a = factory.getBean("proxy", A.class);
	a.m();
}
}

Вывод

дополнительная проблема перед фактической логикой
фактическая бизнес-логика

В MethodBeforeAdvice можно напечатать другую информацию, можно напечатать другую информацию, например, имя метода, параметры метода, объект цели, имя класса объекта цели, класс агента и т.д.

Вам нужно только изменить два класса BeforeAdvisor.java и Test.java.

Файл: BeforeAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvisor implements MethodBeforeAdvice{
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("дополнительная проблема перед фактической логикой");
		System.out.println("метод info:" + method.getName() + " " + method.getModifiers());
		System.out.println("информация об аргументе:");
		for(Object arg: args)
			System.out.println(arg);
		System.out.println("объект целевой: " + target);
		System.out.println("имя класса объекта целевой: " + target.getClass().getName());
	}
}

Файл: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	A a = factory.getBean("proxy", A.class);
        System.out.println("имя класса прокси: " + a.getClass().getName());
	a.m();
}
}

Вывод

имя класса прокси: com.w3codebox.A$EnhancerByCGLIB$409872b1
дополнительная проблема перед фактической логикой
информация о методе: m 1
информация об аргументе:
Объект целевой: com.w3codebox.A@11dba45
имя класса объекта целевой: com.w3codebox.A
фактическая бизнес-логика

Пример AfterReturningAdvice

Создать класс, содержащий фактическую бизнес-логику.

Файл: A.java

как и в предыдущем примере

Теперь создайте класс консультанта, реализующий интерфейс AfterReturningAdvice.

Файл: AfterAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterAdvisor implements AfterReturningAdvice{
	@Override
	public void afterReturning(Object returnValue, Method method,
         Object[] args, Object target) throws Throwable {
		System.out.println("дополнительное внимание после возвращения совета");
	}
}

Создайте файл xml, как в предыдущем примере, вам нужно только изменить класс консультанта здесь.

Файл: applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AfterAdvisor">
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

Файл: Test.java

как и в предыдущем примере

Вывод

фактическая бизнес-логика
дополнительная проблема после возвращения совета

3) Пример MethodInterceptor (AroundAdvice)

Создать класс, содержащий фактическую бизнес-логику.

файл: A.java

как и в предыдущем примере

Теперь создайте класс консультанта, реализующий интерфейс MethodInterceptor.

файл: AroundAdvisor.java

package com.w3codebox;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdvisor implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object obj;
		System.out.println("дополнительная проблема перед фактической логикой");
		obj = mi.proceed();
		System.out.println("дополнительная проблема после фактической логики");
		return obj;
	}
}

Создайте файл xml, как в предыдущем примере, вам нужно только изменить класс консультанта здесь.

Файл: applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AroundAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

Файл: Test.java

как и в предыдущем примере

Вывод

дополнительная проблема перед фактической логикой
фактическая бизнес-логика
дополнительная проблема после фактической логики

Пример ThrowsAdvice

Создать класс, содержащий фактическую бизнес-логику.

файл: Validator.java

package com.w3codebox;
public class Validator {
	public void validate(int age) throws Exception{
		if(age<18){
			throw new ArithmeticException("Not Valid Age");
		}
		else{}}
			System.out.println("голос подтвержден");
		}
	}
}

Теперь создайте класс顾问, который реализует интерфейс ThrowsAdvice.

Файл: ThrowsAdvisor.java

package com.w3codebox;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsAdvisor implements ThrowsAdvice{
	public void afterThrowing(Exception ex){
		System.out.println("дополнительная проблема, если возникает исключение");
	}
}

Создайте файл xml, как в предыдущем примере, вам нужно только изменить классы Validator и Advisor.

Файл: applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.Validator"></bean>
<bean id="ba" class="com.w3codebox.ThrowsAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

Файл: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	Validator v=factory.getBean("proxy",Validator.class);
	try{
	v.validate(12);
	catch(Exception e){e.printStackTrace();}
}
}

Вывод

java.lang.ArithmeticException: Неверный возраст
дополнительная проблема, если возникает исключение
	at com.w3codebox.Validator.validate(Validator.java:7)
	at com.w3codebox.Validator$FastClassByCGLIB$562915cf.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invoke
Joinpoint(Cglib2AopProxy.java:692)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.
invoke(ThrowsAdviceInterceptor.java:124)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.
intercept(Cglib2AopProxy.java:625)
	at com.w3codebox.Validator$EnhancerByCGLIB$4230ed28.validate(<generated>)
	at com.w3codebox.Test.main(Test.java:15)