Spring6 AOP2 ADVICE
来源:互联网 发布:期货交易软件开发 编辑:程序博客网 时间:2024/06/10 04:23
此外,在jointcut出现异常时,具体调用哪个afterThrowing方法,这就涉及到类型判别,最符合类型判别的将会被调用Spring
Advice types in spring
AOP 通知类型1、BeforeAdvice:前置通知需实现MethodBeforeAdvice,但是该接口的Parent是BeforeAdvice,致于什么用处我想可能是扩展性需求的设计吧。或者Spring未来也并不局限于Method的JoinPoint(胡乱猜测)。BeforeAdvice可以修改目标的参数,也可以通过抛出异常来阻止目标运行。
2、AfterreturningAdvice:实现AfterreturningAdvice,我们无法修改方法的返回值,但是可以通过抛出异常阻止方法运行。
3、AroundAdvice:Spring 通过实现MethodInterceptor(aopalliance)来实现包围通知,最大特点是可以修改返回值,当然它在方法前后都加入了自己的逻辑代码,因此功能异常强大。通过MethodInvocation.proceed()来调用目标方法(甚至可以不调用)。
4、ThrowsAdvice:通过实现若干afterThrowing()来实现。
5、IntroductionInterceptor:Spring 的默认实现为DelegatingIntroductionInterceptor
method Before
org.springframework.aop.BeforeAdvice
org.springframework.aop.MethodBeforeAdvice
Called before the target
method is invoked After org.springframework.aop.AfterReturningAdvice Called after the target
method returns Throws org.springframework.aop.ThrowsAdvice Called when target
method throws an
exception 实现MethodBeforeAdvice接口。
//逻辑业务接口
package study.spring.lesson04.advice;
public interface ILogin {
boolean login(String username,String password);
}
//目标类(被代理的类)包含核心逻辑业务
package study.spring.lesson04.advice;
public class LoginAction implements ILogin{
public boolean login(String username, String password) {
if ("zhangsan".equals(username))
throw new RuntimeException();
else if ("lisi".equals(username) && "1234".equals(password))
return true;
else
return false;
}
}
//实现methodBeforAdvice
package study.spring.lesson04.advice;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
public class LoginBeforAdvice implements MethodBeforeAdvice {//必须实现此方法
private Log log = LogFactory.getLog(LoginBeforAdvice.class);
public void before(Method method, Object[] args, Object target)//通知的具体实现
throws Throwable {
if(ILogin.class.isAssignableFrom(target.getClass())){
String username = (String)args[0];
log.info("User[" + username + "]is logining");
}
}
}
代理类调用方法时,真正运行的是每个目标类的真正方法,会根据XML当中配置的接口查询相应的实现了methodBeforAdvice方法的类然后运行,再运行目标类的真正业务逻辑方法,args包含了该方法所有的参数。
xml 代码
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="loginTarget" class="study.spring.lesson04.advice.LoginAction"/>
<bean id="loginBeforeAdvice" class="study.spring.lesson04.advice.LoginBeforAdvice"/>
<bean id="login" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"> //目标类的指定
<ref local="loginTarget"/>
</property>
<property name="proxyInterfaces"> //应用通知的接口
<value>study.spring.lesson04.advice.ILogin</value>
</property>
<property name="interceptorNames"> //通知的指定
<list>
<value>loginBeforeAdvice</value>
</list>
</property>
</bean>
</beans>
测试类
package test.study.spring.lesson04;
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;
import study.spring.lesson04.advice.ILogin;
import junit.framework.TestCase;
public class TestAop extends TestCase {
public void testAop(){
Resource res = new ClassPathResource("beans.xml");
BeanFactory bf = new XmlBeanFactory(res);
ILogin login =(ILogin) bf.getBean("login"); //运用了FactoryBean当中的getObject方法
login.login("lisi", "1234"); //运用了Proxy.newProxyInstance方法
}
}
org.springframework.aop.framework.ProxyFactoryBean是spring框架中很重要的一个类,它可以在不改变被代理类的前提下对其增加一些行为。
实现AfterReturningAdvice接口
//逻辑业务接口
package study.spring.lesson04.advice;
public interface ILogin {
boolean login(String username,String password);
}
//目标类(被代理的类)包含核心逻辑业务
package study.spring.lesson04.advice;
public class LoginAction implements ILogin{
public boolean login(String username, String password) {
if ("zhangsan".equals(username))
throw new RuntimeException();
else if ("lisi".equals(username) && "1234".equals(password))
return true;
else
return false;
}
}
//实现AfterReturningAdvice接口
package study.spring.lesson04.advice;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
public class LoginAfterAdvice implements AfterReturningAdvice {
private Log log = LogFactory.getLog(LoginAfterAdvice.class);
public void afterReturning(Object returnvalue, Method method,
Object[] args, Object target) throws Throwable {
if (ILogin.class.isAssignableFrom(target.getClass())) {
boolean flag = (Boolean) returnvalue;
String username = (String) args[0];
if (flag)
log.info("User[" + username + "] login success");
else
log.info("User[" + username + "] login failed");
}
}
}
xml 代码
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="loginTarget" class="study.spring.lesson04.advice.LoginAction"/>
<bean id="loginBeforeAdvice" class="study.spring.lesson04.advice.LoginBeforAdvice"/>
<bean id="login" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="loginTarget"/>
</property>
<property name="proxyInterfaces">
<value>study.spring.lesson04.advice.ILogin</value>
</property>
<property name="interceptorNames">
<list>
<value>loginBeforeAdvice</value>
<value>LoginAfterAdvice</value> //
</list>
</property>
</bean>
<bean id="LoginAfterAdvice" class="study.spring.lesson04.advice.LoginAfterAdvice"/>
</beans>
实现ArondAdvice接口
//逻辑业务接口
package study.spring.lesson04.advice;
public interface ILogin {
boolean login(String username,String password);
}
//目标类(被代理的类)包含核心逻辑业务
package study.spring.lesson04.advice;
public class LoginAction implements ILogin{
public boolean login(String username, String password) {
if ("zhangsan".equals(username))
throw new RuntimeException();
else if ("lisi".equals(username) && "1234".equals(password))
return true;
else
return false;
}
}
//实现ArondAdvice接口
package study.spring.lesson04.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LoginAroundAdvice implements MethodInterceptor { //必须实现此接口
private Log log = LogFactory.getLog(LoginAroundAdvice.class);
public Object invoke(MethodInvocation invocation) throws Throwable {
if (ILogin.class.isAssignableFrom(invocation.getMethod()
.getDeclaringClass())) {
String username = (String) invocation.getArguments()[0];
log.info("User[" + username + "]is logining");
if ((Boolean) invocation.proceed()) { //此处可以控制目标对象的方法的调用
log.info("User[" + username + "] login success");
return true;
} else {
log.info("User[" + username + "] login failed");
return false;
}
}
return invocation.proceed();
}
}
xml代码实现
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="loginTarget" class="study.spring.lesson04.advice.LoginAction"/>
<bean id="loginBeforeAdvice" class="study.spring.lesson04.advice.LoginBeforAdvice"/>
<bean id="login" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="loginTarget"/>
</property>
<property name="proxyInterfaces">
<value>study.spring.lesson04.advice.ILogin</value>
</property>
<property name="interceptorNames">
<list>
<value>loginBeforeAdvice</value>
<value>LoginAfterAdvice</value>
<value>LoginAroundAdvice</value>
</list>
</property>
</bean>
<bean id="LoginAfterAdvice" class="study.spring.lesson04.advice.LoginAfterAdvice"/>
<bean id="LoginAroundAdvice" class="study.spring.lesson04.advice.LoginAroundAdvice"/>
</beans>
- Spring6 AOP2 ADVICE
- spring6
- AOP2
- spring aop2
- spring AOP2
- Advice
- advice
- advice
- Spring6:Spring中的事务管理
- Spring6种配置模板
- spring的AOP2
- Spring基础知识(6)-AOP2
- Spring AOP2
- Some advice
- Advice 通知
- Advice 通知
- express---advice
- 002 Advice
- 工作流流程状态管理及变迁
- C/C++学习笔记:使用指针交换数据源码
- 学好php的几点心得
- 用telnet登录163邮箱
- C/C++学习笔记:指向指针的指针
- Spring6 AOP2 ADVICE
- SQL操作全集
- TCP/IP详解(3)
- C/C++学习笔记:指针与数组
- 《Spring Web Flow 介绍》PPt文档
- ServletContextAware Struts2和Spring2中都有 到底用哪一个?
- Document对象详解 (JS)
- gsoap入门指引
- 一个动态调用DLL的源码