English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
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 returning
Aplica-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 throwing
Se o método de lógica de negócio real lançar uma exceção, aplique-o.
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.javapackage 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.
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.
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.
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.
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