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>