spring-aop原理和案例

本文介绍 Spring AOP 的实现方式,包括接口定义、前置通知、后置通知、环绕通知及异常通知等,并通过示例代码展示如何配置代理对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.接口

package com.wl.aop;

public interface ServiceOneInter {
    public void sayHello();
}

 

package com.wl.aop;

public interface ServiceTwoInter {
    public void sayBye();
}


2.前置 通知

package com.wl.aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
/**
 *配置前置通知
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice{

    @Override
    public void before(Method method, Object[] args, Object target)
            throws Throwable {
        System.out.println("**********************************");
        System.out.println("开始写日志......" + method.getName());
    }
}

3.后置通知

package com.wl.aop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class MyAfterReturningAdvice implements AfterReturningAdvice{

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args,
            Object target) throws Throwable {
        System.out.println("关闭资源......");
    }

}
4.环绕通知

package com.wl.aop;

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

public class MyMethodInterceptor implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
        System.out.println("调用方法前执行......");
        Object obj = arg0.proceed();
        System.out.println("调用方法后执行......");
        return obj;
    }

}
5.异常通知

package com.wl.aop;

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;
/**
 * ThrowsAdvice该接口为标识性接口,没有任何方法,但实现该接口的类必需要有如下情形
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(Method m, Object[] os,Object target,Exception e){
        System.out.println("异常通知......" + e.getMessage());
    }
    
}

 

6.被代理对象

package com.wl.aop;

/**
 * 被代理对象
 */
public class Service implements ServiceOneInter,ServiceTwoInter{
    
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void sayHello() {
        System.out.println("Hi:" + name);
    }
    @Override
    public void sayBye() {
        System.out.println("say bay ......");
//        int i = 1/0;
    }
    
}
7.测试类:

package com.wl.aop;

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

public class Test {
    
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/wl/aop/spring-core.xml");
        ServiceOneInter serviceOneInter = (ServiceOneInter) ac.getBean("proxyFactoryBean");
        //spring aop中,当你通过代理对象去实现aop的时候,获取的ProxyFactoryBean是什么类型?
        //返回的是一个代理对象,如果目标对象实现了接口,则spring使用jdk动态代理技术,如果目标对象没有实现接口,则spring使用了CGLIB技术。
        System.out.println("serviceOneInter类型:" + serviceOneInter);
        serviceOneInter.sayHello();
        ((ServiceTwoInter)serviceOneInter).sayBye();
    }
}

 

8.配置文件bean.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 配置被代理的对象 -->
<bean id="service" class="com.wl.aop.Service">
    <property name="name" value="zhangsan"/>
</bean>
<!-- 配置前置通知 -->
<bean id="myMethodBeforeAdvice" class="com.wl.aop.MyMethodBeforeAdvice"/>
<!-- 后置通知 -->
<bean id="myAfterReturningAdvice" class="com.wl.aop.MyAfterReturningAdvice"/>
<!-- 配置环绕通知 -->
<bean id="myMethodInterceptor" class="com.wl.aop.MyMethodInterceptor"/>

<!-- 异常通知 -->

<bean id="myThrowsAdvice" class="com.wl.aop.MyThrowsAdvice"/>

<!-- 定义前置通知的切入点(引用通知,某些连接点织入通知,某些不通知) -->
<bean id="myMethodBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice" ref="myMethodBeforeAdvice"></property>
    <property name="mappedNames">
        <list>
            <value>sayHello</value>
            <!-- <value>sys*</value> -->
        </list>
    </property>
</bean>
<!-- 配置代理对象 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 代理接口集 -->
    <property name="proxyInterfaces">
        <list>
            <value>com.wl.aop.ServiceOneInter</value>
            <value>com.wl.aop.ServiceTwoInter</value>
        </list>
    </property>
    <property name="interceptorNames">
        <list>
            <!-- 织入通知 -->
            <!-- <value>myMethodBeforeAdvice</value> -->
            <value>myAfterReturningAdvice</value>
            <value>myMethodInterceptor</value>
            <value>myThrowsAdvice</value>

            <!-- 使用自定义切入点 -->
            <value>myMethodBeforeAdviceFilter</value>

        </list>
    </property>
    <!-- 配置被代理对象, 可以指定-->
    <property name="target" ref="service"/>
</bean>
</beans>



 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值