07、Spring框架入门:Schemabase

这里写目录标题

    • 1.具体实现步骤
  • 2.实现步骤
  • 3.注意

1.具体实现步骤

  • 确定切点—a()
  • 通知–
  • 织入成切面

2.实现步骤

导入jar包:

  • aopalliance.jar
  • aspectjweaver.jar
  • commons-logging-1.1.3.jar
  • spring-aop-4.1.6.RELEASE.jar
  • spring-aspects-4.1.6.RELEASE.jar
  • spring-beans-4.1.6.RELEASE.jar
  • spring-context-4.1.6.RELEASE.jar
  • spring-core-4.1.6.RELEASE.jar
  • spring-expression-4.1.6.RELEASE.jar

具体实现:

package com.test;

import com.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
   
     //测试类

    public static void main(String[] args) {
   
     
        //[1]解析appxml
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContexxt.xml");
        //[2]获得user对象
        User us = app.getBean("us", User.class);
        us.b("DQCGM");
    }
}

package com.pojo;

public class User {
   
     //示例类

    public void a() {
   
     
        /*int  a =10/0;*/
        System.out.println("--我是方法A-");
    }

    public void b(String z) {
   
     
        //int a = 5 / 0;
        System.out.println("--我是方法B-");
    }

    public void c() {
   
     
        System.out.println("--我是方法C-");
    }
}

package com.advice;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterAdvice implements AfterReturningAdvice {
   
     //后置通知
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
   
     
        /**
         * o:切点返回值
         * method:切点所在的方法对象
         * objects:切点中参数
         * o1:切点所在类
         * */
        // System.out.println(o+"---"+method+"--"+objects+"---"+o1);
        System.out.println("--后置通知--");
    }
}

package com.advice;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class BeforAdvice implements MethodBeforeAdvice{
   
     //方法前置通知
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
   
     
       // System.out.println(method+"--"+objects[0]+"---"+o);
        /**
         * method:获得切点的方法对象
         * objects:参数值
         * o:切点所在的类
         * */
        System.out.println("--方法前置通知--");
    }
}

package com.advice;

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

public class RunAdvice implements MethodInterceptor {
   
     //环绕通知
    /**
     * 环绕通知一般不结合前置和后置通知使用
     * <p>
     * methodInvocation
     * 封装是切点的方法对象和所在的类
     */
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
   
     
        System.out.println("--环绕通知-前--");
        Object o = methodInvocation.proceed();
        System.out.println("--环绕通知-后--");
        return o;
    }
}

package com.advice;

import org.springframework.aop.ThrowsAdvice;

public class ThrAdvice implements ThrowsAdvice {
   
     //异常通知

    public void afterThrowing(Exception ex) throws Throwable {
   
     
        System.out.println("--异常通知--");
    }
}

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="us" class="com.pojo.User"></bean>

    <!--创建前置通知-->
    <bean id="befor" class="com.advice.BeforAdvice"></bean>
    <!--配置后置通知-->
    <bean id="after" class="com.advice.AfterAdvice"></bean>
    <!--配置环绕通知-->
    <bean id="run" class="com.advice.RunAdvice"></bean>
    <!--配置异常通知-->
    <bean id="thr" class="com.advice.ThrAdvice"></bean>

    <!--织入成一个切面-->
    <aop:config>
        <!--配置切点  含义:user中所有的b方法-->
        <aop:pointcut id="pt1" expression="execution(* com.pojo.User.b(..))"></aop:pointcut>
        <!--配置切点  含义:user中所有的方法-->
        <aop:pointcut id="pt2" expression="execution(* com.pojo.User.*(..))"></aop:pointcut>
        <!--配置切点  含义:pojo包下的所有类的所有方法-->
        <aop:pointcut id="pt3" expression="execution(* com.pojo.*.*(..))"></aop:pointcut>

        <!--配置通知-->
        <aop:advisor advice-ref="befor" pointcut-ref="pt1"></aop:advisor>
        <aop:advisor advice-ref="after" pointcut-ref="pt1"></aop:advisor>
        <aop:advisor advice-ref="run" pointcut-ref="pt1"></aop:advisor>
        <aop:advisor advice-ref="thr" pointcut-ref="pt1"></aop:advisor>
    </aop:config>
</beans>

运行结果:


正常情况:
*
异常情况:(把User类中b()方法5/0的注释放开即可)
*

3.注意

  • AOP的底层默认的使用是JDK代理 我们也可以手动的开始CGLib代理方式
<!-- cglib代理方式 --> 
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> 

  • Spring自动的开启 log4j.properties 的日志操作