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

Exemplo de configuração xml do Spring AOP AspectJ

O Spring permite que você defina aspectos, conselhos e切入点 em arquivos xml.

Na página anterior, já vimos um exemplo de aop usando anotações. Agora, vamos ver o mesmo exemplo através do arquivo de configuração xml.

Vamos ver os elementos xml usados para definir o conselho.

aop: before Aplica-se antes da chamada do método de lógica de negócio real. aop: after Aplica-se após a chamada do método de lógica de negócio real. aop: after returningAplica-se após a chamada do método de lógica de negócio real. Pode ser usado para interceptar o valor de retorno da notificação. aop: around Aplica-se antes e após a chamada do método de lógica de negócio real. aop: after throwingSe o método de lógica de negócio real lançar uma exceção, aplique-o.
Atenção: Para entender o conceito de aop e suas vantagens, acesse aqui. Tutorial de conceito de AOP

1aop: before

Aplique o "conselho AspectJ antes da lógica de negócio" antes do método de lógica de negócio real. Você pode fazer qualquer ação aqui, por exemplo, conversão, autenticação, etc.

Crie uma classe que contenha a lógica de negócio real.

Arquivo: Operation.java
package com.w;3codebox;
public class Operation{
	public void msg(){System.out.println("método msg invocado");}
	public int m(){System.out.println("método m invocado");return 2;}
	public int k(){System.out.println("método k invocado");return 3;}
}

Agora, crie uma classe que contenha o aspecto antes da sugestão.

Arquivo: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
public class TrackOperation{
	public void myadvice(JoinPoint jp)//é conselho
	{
		System.out.println("concern adicional");
		//System.out.println("Assinatura do método: "  + jp.getSignature());
	}
}

Agora crie o arquivo applicationContext.xml que define o bean.

Arquivo: 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:aop="http://www.springframework.org/schema/aop
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<bean id="opBean" class="com.w3codebox.Operation">	</bean>
<bean id="trackAspect" class="com.w3codebox.TrackOperation"></bean>
<aop:config>
  <aop:aspect id="myaspect" ref="trackAspect" >
     <!-- @Before -->
     <aop:pointcut id="pointCutBefore"	expression="execution(* com.w3codebox.Operation.*(..))" />
     <aop:before method="myadvice" pointcut-ref="pointCutBefore" />
  </aop:aspect>
</aop:config>
</beans>

Agora, chamemos o método real.

Arquivo: Test.java

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation e = (Operation) context.getBean("opBean");
		System.out.println("chamando msg...");
		e.msg();
		System.out.println("chamando m...");
		e.m();
		System.out.println("chamando k...");
		e.k();
	}
}

Saída

chamando msg...
concern adicional
método msg() invocado
chamando m...
concern adicional
m() método invocado
chamando k...
concern adicional
método k() invocado

Como você pode ver, antes de chamar os métodos msg(), m() e k(), também são impressas outras questões.


2Exemplos após a aop:

Após a chamada da lógica de negócio real, aplica-se o AspectJ após a notificação. Ele pode ser usado para manter logs, segurança, notificações, etc.

Aqui, supomos Operation.java , TrackOperation.java e}} Test.java O arquivo é o mesmo que o exemplo em aop:

Agora crie o arquivo applicationContext.xml que define o bean.

Arquivo: 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:aop="http://www.springframework.org/schema/aop
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<bean id="opBean" class="com.w3codebox.Operation">	</bean>
<bean id="trackAspect" class="com.w3codebox.TrackOperation"></bean>
<aop:config>
  <aop:aspect id="myaspect" ref="trackAspect" >
     <!-- @After -->
     <aop:pointcut id="pointCutAfter"	expression="execution(* com.w3codebox.Operation.*(..))" />
     <aop:after método="myadvice" pointcut-ref="pointCutAfter" />
  </aop:aspect>
</aop:config>
</beans>

Saída

chamando msg...
método msg() invocado
concern adicional
chamando m...
m() método invocado
concern adicional
chamando k...
método k() invocado
concern adicional

Você pode ver que após a chamada dos métodos msg(), m() e k(), surgem outros problemas.


3exemplo de after: aop

Ao usar o conselho após o retorno, podemos obter o resultado no conselho.

Criar

Arquivo: Operation.java

package com.w;3codebox;
public class Operation{
	public int m(){System.out.println("m() método invocado");return 2;}
	public int k(){System.out.println("k() método invocado");return 3;}
}

Criar a classe de aspecto contida no conselho de retorno.

Arquivo: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
public class TrackOperation{
	public void myadvice(JoinPoint jp,Object result)//é conselho (após conselho)
	{
		System.out.println("concern adicional");
		System.out.println("Assinatura do método: "  + jp.getSignature());
		System.out.println("Resultado no conselho: "+result);
		System.out.println("fim do conselho após o retorno...");
	}
}

Arquivo: 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:aop="http://www.springframework.org/schema/aop
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<bean id="opBean" class="com.w3codebox.Operation">	</bean>
<bean id="trackAspect" class="com.w3codebox.TrackOperation"></bean>
<aop:config>
  <aop:aspect id="myaspect" ref="trackAspect" >
     <!-- @AfterReturning -->
     <aop:pointcut id="pointCutAfterReturning"	expression="execution(* com.w3codebox.Operation.*(..))" />
     <aop:after-método retornando="myadvice" retornando="result" pointcut-ref="pointCutAfterReturning" />
  </aop:aspect>
</aop:config>
</beans>

Arquivo: Test.java

Agora criamos a classe Test para chamar métodos reais.

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation e = (Operation) context.getBean("opBean");
		System.out.println("chamando m...");
		System.out.println(e.m());
		System.out.println("chamando k...");
		System.out.println(e.k());
	}
}

Saída

chamando m...
m() método invocado
concern adicional
Assinatura do método: int com.w3codebox.Operation.m()
Resultado no conselho: 2
fim do conselho após o retorno...
2
chamando k...
método k() invocado
concern adicional
Assinatura do método: int com.w3codebox.Operation.k()
Resultado no conselho: 3
fim do conselho após o retorno...
3

Você pode ver que o valor de retorno é impresso duas vezes, uma vez pela classe TrackOperation e outra vez pela classe Test.


4、aop: around

Aconselhamento ao redor do AspectJ é aplicado antes e após a chamada do método de lógica de negócios real.

Crie uma classe

Arquivo: Operation.java

package com.w;3codebox;
public class Operation{
	public void msg(){System.out.println("msg() é invocado");}
	public void display(){System.out.println("display() é invocado");}
}

Crie uma classe que envolve o conselho.

Você precisa passar para o método de conselho PreceedingJoinPoint citado, para que possamos chamar o método proceed().

Arquivo: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.ProceedingJoinPoint;
public class TrackOperation
{
	public Object myadvice(ProceedingJoinPoint pjp) throws Throwable 
	{
		System.out.println("Concerno adicional antes de chamar o método real");
		Object obj = pjp.proceed();
		System.out.println("Concerno adicional após a chamada do método real");
		retorne obj;
	}
}

Arquivo: 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:aop="http://www.springframework.org/schema/aop
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<bean id="opBean" class="com.w3codebox.Operation">	</bean>
<bean id="trackAspect" class="com.w3codebox.TrackOperation"></bean>
<aop:config>
  <aop:aspect id="myaspect" ref="trackAspect" >
     <!-- @Around -->
     <aop:pointcut id="pointCutAround"	expression="execution(* com.w3codebox.Operation.*(..))" />
     <aop:around method="myadvice" pointcut-ref="pointCutAround" />
  </aop:aspect>
</aop:config>
</beans>

Arquivo: Test.java

Agora criamos a classe Test para chamar métodos reais.

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml");
		Operation op = (Operation) context.getBean("opBean");
		op.msg();
		op.display();
	}
}

Saída

Concern adicional antes de chamar o método real
msg() é invocado
Concern adicional após a chamada do método real
Concern adicional antes de chamar o método real
display() é invocado
Concern adicional após a chamada do método real

Você pode ver que antes e após a chamada do método msg() e do display(), também são impressas outras questões.


5、aop: after-throwing

Usando o conselho after, podemos imprimir a exceção na classe TrackOperation. Vamos ver um exemplo de conselho AfterThrowing do AspectJ.

Criar uma classe que contém a lógica de negócios.

Arquivo: Operation.java

package com.w;3codebox;
public class Operation{
	public void validate(int age)throws Exception{
	if(age<18){
		throw new ArithmeticException("Idade não válida");
	}
	else{
		System.out.println("Obrigado para voto");
	}
	}
}

Criar a classe do aspecto que será executada após o conselho ser disparado.

Aqui, precisamos passar uma referência de Throwable para que possamos interceptar a exceção aqui.

Arquivo: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
public class TrackOperation{
	public void myadvice(JoinPoint jp,Throwable error)//é conselho
	{
		System.out.println("concern adicional");
		System.out.println("Assinatura do método: "  + jp.getSignature());
		System.out.println("A exceção é: "+error);
		System.out.println("fim do after throwing advice...");
	}
}

Arquivo: 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:aop="http://www.springframework.org/schema/aop
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<bean id="opBean" class="com.w3codebox.Operation">	</bean>
<bean id="trackAspect" class="com.w3codebox.TrackOperation"></bean>
<aop:config>
  <aop:aspect id="myaspect" ref="trackAspect" >
     <!-- @AfterThrowing -->
     <aop:pointcut id="pointCutAfterThrowing"	expression="execution(* com.w3codebox.Operation.*(..))" />
     <aop:after-throwing method="myadvice" throwing="error" pointcut-ref="pointCutAfterThrowing" />
  </aop:aspect>
</aop:config>
</beans>

Arquivo: Test.java

Agora criamos a classe Test para chamar métodos reais.

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation op = (Operation) context.getBean("opBean");
		System.out.println("chamando validate...");
		try{
			op.validate(19);
		}catch(Exception e){System.out.println(e);}
		System.out.println("chamando validate novamente...");
		try{
		    op.validate(11);
		}catch(Exception e){System.out.println(e);}
	}
}

Saída

chamando validate...
Obrigado pelo voto
chamando validate novamente...
concern adicional
Assinatura do método: void com.w3codebox.Operation.validate(int)
A exceção é: java.lang.ArithmeticException: Idade não válida
fim do conselho após lançar exceção...
java.lang.ArithmeticException: Idade não válida