Spring AOP

2018-07-19  本文已影响2人  tingshuo123

aop:面向切面编程,个人的理解就是,在不改变目标程序源码码的情况下,动态的在程序执行之前或者之后执行一些业务方法。

加入现在有一个登录注册的业务接口:

package com.project.service;

public interface IUserService {
    
    public void login();
    
    public void register();
}

接口实现类:

package com.project.service.impl;

import com.project.service.IUserService;

public class UserServiceImpl implements IUserService {

    @Override
    public void login() {
        System.out.println("执行登录业务中");

    }

    @Override
    public void register() {
        System.out.println("执行注册业务中");

    }

}

使用通知,添加一些功能,如记录用户登录时间、日志记录等。

前置通知,实现 MethodBeforeAdvice 接口

package com.project.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class Advice01 implements MethodBeforeAdvice{

    @Override
    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
        
        System.out.println("记录登录时间。。。");
    }
}

后置通知,需实现 AfterReturningAdvice 接口

package com.project.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class Advice02 implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
        
        System.out.println("记录日志");
    }

}

环绕通知,实现MethodInterceptor 导 apache 的包

package com.project.advice;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class Advice03 implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {

        // 执行目标业务之前执行
        System.out.println("执行业务方法之前执行");

        // 调用目标程序的方法
        Object result = arg0.proceed();

        // 执行目标业务之前执行
        System.out.println("执行业务方法之后执行");

        return result;
    }

}

配置 spring 的配置文件,springConfig.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册实现类 -->
    <bean id="UserServiceImpl" class="com.project.service.impl.UserServiceImpl"></bean>
    
    <!-- 注册通知类 -->
    <bean id="Advice01" class="com.project.advice.Advice01"></bean>
    <bean id="Advice02" class="com.project.advice.Advice02"></bean>
    <bean id="Advice03" class="com.project.advice.Advice03"></bean>
    
    <!-- 注册动态代理工厂对象 -->
    <bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 注入目标对象 -->
        <property name="target" ref="UserServiceImpl"></property>
        <!-- 注入通知对象 -->
        <property name="interceptorNames" value="Advice01, Advice02, Advice03"></property>
    </bean>
</beans>

测试函数:

package com.project.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.project.service.IUserService;

public class TestMain {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml");
        IUserService service = (IUserService) context.getBean("proxyFactory");
        service.login();
    }

测试结果:


结果

有五种通知,这里只简单介绍了常用的三种通知的使用方法。

上一篇下一篇

猜你喜欢

热点阅读