AOP面向切面编程
面向切/方面(AOP)编程:核心就是代理模式(jdk动态代理)面向接口(只能拦截实现接口的类)、cglib代理
代理模式就是控制对象的访问(拦截),手工编写拦截访问类需要实现InvocationHandler接口。
1、JDK动态代理(代理)类(要有接口、有实现接口的类、代理对象要实现InvocationHandler、测试类、(即:接口,
目标类,拦截器,客户端))
public class UserFactoryBean implements InvocationHandler {
private Object target;
//拦截器
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(“事务日志的处理”);
Object result=method.invoke(target/*目标*/,args/*参数*/);
System.out.println(“事务日志的提交”);
return result;
}
public void setTarget(Object target) {
this.target = target;
}
//返回拦截后的对象
public Object getProxy(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
}
public class test {
public static void main(String[] args) {
//没有被拦截的
UserService us=new UserServiceImpl();
us.update();
us.delete();
//调用拦截
UserFactoryBean userFactoryBean=new UserFactoryBean();
userFactoryBean.setTarget(us);
//获取代理对象
UserService userService= (UserService) userFactoryBean.getProxy();
//拦截结果
userService.update();
userService.delete();
}
}
2、前置增强
增强类(前置实现接口:MethodBeforeAdvice):
public class BeforeGreetingAdvice implements MethodBeforeAdvice {
@Override
public void before(Method arg0/*要执行的方法*/, Object[] arg01/*此处的数组指的是(1)的参数因为可能有多个
参数所以用数组*/, Object arg02) throws Throwable {
System.out.println(arg0.getName());
System.out.println(“hello “+arg01[0]);
}
}
接口:
public interface Waietr {
public void serverTo(String name/*(1)此处可以有多个参数*/);
public void greetTo(String name);
}
实现类:
public class WaiterNative implements Waietr {
@Override
public void serverTo(String name) {
System.out.println(“serverTo”);
}
@Override
public void greetTo(String name) {
System.out.println(“greetTo”);
}
}
配置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"
//Aop加上这一句
xmlns:aop=“http://www.springframework.org/schema/aop"
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
//Aop在加上这两句
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd" >
<bean id="waiter" class="springAOP.springlanjie.WaiterNative"></bean>
<bean id="before" class="springAOP.springlanjie.BeforeGreetingAdvice"></bean>
<bean id="waiterProxy" class="org.springframework.aop.framework.ProxyFactoryBean"/*此处的类必需是这
个类*/
p:target-ref=“waiter”
p:interceptorNames=“before”
p:interfaces=“springAOP.springlanjie.Waietr”
>
/*
*<property name=“target” ref=“sjj”></property>
*<property name=“interceptorNames” value=“before”></property>
*<property name=“proxyinterfaces” value=“springAOP.springlanjie.practice.User”></property>
*/
</bean>
</beans>
测试类:
public class test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("springAOP/springlanjie/bean.xml");
//获取代理对象
Waietr/*此处必须是接口不能是实现类*/ waietr=context.getBean(“waiterProxy”/*获取的是拦截后的bean的
id*/,Waietr.class/*此处必须是接口*/);
waietr.greetTo(“jack”);
waietr.serverTo(“rose”);
}
}
3、后置增强
增强类(后置实现接口:AfterReturningAdvice):
public class AfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(“嘿嘿嘿”);
}
}
配置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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd" >
<bean id="waiter" class="springAOP.springlanjie.WaiterNative"></bean>
<!--前置拦截-->
<bean id="before" class="springAOP.springlanjie.BeforeGreetingAdvice"></bean>
<!--后置拦截-->
<bean id="after" class="springAOP.springlanjie.AfterAdvice"></bean>
<bean id="waiterProxy" class="org.springframework.aop.framework.ProxyFactoryBean"
p:target-ref="waiter"
p:interceptorNames="before,after"
p:interfaces="springAOP.springlanjie.Waietr"
></bean>
</beans>
4、环绕拦截
增强类(环绕实现接口:MethodInterceptor):
public class DebugInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation/*要执行的方法*/) throws Throwable {
/*前置增强*/
System.out.println(“Before:["+methodInvocation+”]”);
System.out.println(methodInvocation.getMethod());
/*函数本身执行(.proceed)*/
Object rval=methodInvocation.proceed();
/*后置增强*/
System.out.println(“after”);
/*执行函数的返回值*/
return rval;
}
}
XML配置:
<bean id="waiter" class="springAOP.springlanjie.WaiterNative"></bean>
<bean id="debug" class="springAOP.springlanjie.DebugInterceptor"></bean>
<bean id="waiterProxy" class="org.springframework.aop.framework.ProxyFactoryBean"
p:target-ref="waiter"
p:interceptorNames="debug"
p:proxyInterfaces="springAOP.springlanjie.Waietr"
></bean>