JAVA--高级基础开发

情到浓时终转凉″ 提交于 2020-03-13 12:28:30

第二章 Spring-AOP

1.1 Spring-AOP概述

  1. AOP:(全称是Aspect Oriented Programming)面向切面编程。AOPoop的延续,是函数式编程一种衍生泛型,利用AOP可以对业务逻辑的各个部分进行分离,从而降低各个部分之间的耦合度,提高程序的可重用性,同时提高了开发的效率。
  2. 简单来说(AOP就是把我们程序中重复的代码抽取出来,在需要执行时,使用动态的代理技术,在不修改源代码的基础上,对我们已有的方法进行增强)。
  3. AOP的作用和优势:作用,在程序运行期间,在不修改源代码的基础上,对已有的方法进行增强。优势:减少重复代码。提高开发的效率,维护方便。
  4. AOP的实现方式: 使用动态的代理技术来完成。
  5. 动态代理有两种方式:一种是基于接口的,一种是基于子类的。

第二章 Spring-AOP的配置【重点】

2.1 SpringAOP的说明

  1. SpringAOP的术语

JoinPoint(连接点): 所谓的连接点就是指那些被拦截的点,Spring中,这些点指的就是方法,因为Spring只支持基于方法的连接点。

PointCut(切入点):所谓饿切入点就是我们要对那些(JoinPonit)进行拦截定义。

Advice(通知/增强):所谓通知是指拦截到(JoinPoint)之后需要做的事情就是通知。

通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。

Introducation(引介):是一种特殊的通知在不修改类代码的前提下,Introducation可以在运行期间为类动态的的添加一些方法或属性。

Target(目标对象):代理的目标对象。

Weaving(织入):就是把增强应用到目标对象创建新的代理对象的过程。Spring采用动态代理织入,而Aspectj采用编译期织入和类装载织入。

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。

Aspect(切面):就是切入点和通知(引介)的结合。

Spring中,框架会会根据目标类是否实现了接口来采用哪种动态代理的方式。

2.2基于XmlAOPde 配置

  1. Jar包的说明

<!—AOP依赖的织入Jar-->

<dependency>

    <groupId>org.aspectj</groupId>

    <artifactId>aspectjweaver</artifactId>

    <version>1.9.5</version>

    <scope>runtime</scope>

</dependency>

  1. Spring配置文件中导入约束

<?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"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xmlns:p="http://www.springframework.org/schema/p"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

        https://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context

        https://www.springframework.org/schema/context/spring-context.xsd

        http://www.springframework.org/schema/aop

        http://www.springframework.org/schema/aop/spring-aop.xsd

">

  1. 配置SpringAOP

 

    <!--配置SpringIOC-->

    <bean id="IAccountDao" class="com.bdit.dao.impl.IAccountDaoImpl"></bean>

    <bean id="IAccountService" class="com.bdit.Service.impl.AccountServiceImpl">

        <property name="iAccountDao" ref="IAccountDao"></property>

    </bean>

  1. 抽取公共日志代码切面类

import org.apache.log4j.Logger;

public class LoggerUtils {

    //获取日志记录器对象

     private Logger logger=Logger.getLogger(LoggerUtils.class);

    public void beforAd(){

        logger.info("***************前置通知*****************");

    }

 public void afterAd(){

        System.out.println("***************后置通知*****************");

    }

}

  1. 配置通知类

<!--配置通知类-->

    <bean id="loggerAd" class="com.bdit.Utils.LoggerUtils"></bean>

  1. 配置AOP

     <!--配置AOP-->

    <aop:config>

        <!--配置切面-->

        <aop:aspect id="logAspect" ref="loggerAd">

        <!--配置切入点-->

            <aop:pointcut id="mypoint" expression="execution(* com.bdit.Service.impl.*.*(..))"/>

            <!--配置通知类型-->

            <!--用于配置前置通知-->

            <aop:before method="beforAd" pointcut-ref="mypoint"></aop:before>

            <!--用于配置后置通知-->

            <aop:after-returning method="afterAd" pointcut-ref="mypoint"></aop:after-returning>

            <!--用于配置异常通知-->

            <aop:after-throwing method="afterexception" pointcut-ref="mypoint"></aop:after-throwing>

            <!--用于配置最终通知类-->

            <aop:after method="after" pointcut-ref="mypoint"></aop:after>

        </aop:aspect>

    </aop:config>

</beans>

  1. 环绕通知

必须添加一个依赖包

<!--aop会用到织入包aspectjrt -->

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjrt</artifactId>

            <version>1.9.5</version>

        </dependency>

  1. Spring配置文件

<!--环绕通知-->

 <aop:around method="aroundMethod" pointcut-ref="mypoint"></aop:around>

  1. 抽取公共日志切面类

public  void aroundMethod(ProceedingJoinPoint point){

        //获取方法执行所需要的参数,返回的是Object的数组

        Object[]args=point.getArgs();

        Account account=(Account)args[0];

        System.out.println("==========>"+account);

        try {

            logger.info("***************开启事物*****************");

            point.proceed(args);//执行的目标方法

            logger.info("***************提交事物*****************");

        } catch (Throwable throwable) {

            logger.info("***************回滚事物*****************");

            throwable.printStackTrace();

        }finally {

            logger.info("***************释放资源*****************");

        }

    }

  1. 测试类

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

 

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations ={"classpath:Spring.xml"})

public class SpringSpp {

   @Autowired

   private IAccountService  iAccountService;

 

   @Test

    public  void apples(){

       Account  account= new Account();

       account.setZid(1);

       account.setMoney(23232.232);

       account.setUid(3);

         iAccountService.save(account);

   }

}

2.3 基于注解的AOP[工程搭建]

  1. 把配置文件的配置替换成注解

<!--基于注解的使用,需要导入一个 context 名称空间的约束-->

<!--开启Spring对注解的支持-->

<!--指定要扫描的包-->

    <context:component-scan base-package="com.bdit"/>

  1. 使用注解配置通知类

@Component  //指定这个类交给Spring管理

public class LoggerUtils {

  1. 在通知类上添加一个@Aspect  此注解的作用就是申明当前类为切面类

@Component  //指定这个类交给Spring管理

@Aspect    //此注解的作用就是申明当前类为切面类

public class LoggerUtils {

  1. 配置通知,使用注解配置通知

 import com.bdit.entify.Account;

import org.apache.log4j.Logger;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

 

@Component  //指定这个类交给Spring管理

@Aspect    //此注解的作用就是申明当前类为切面类

public class LoggerUtils {

    //获取日志记录器对象

     private Logger logger=Logger.getLogger(LoggerUtils.class);

     @Before(value = "execution(* com.bdit.Service.impl.*.*(..))")

    public void beforAd(){

        logger.info("***************前置通知*****************");

    }

    @AfterReturning(value ="execution(* com.bdit.Service.impl.*.*(..))")

    public void afterAd(){

        logger.info("***************后置通知*****************");

    }

    @AfterThrowing(value ="execution(* com.bdit.Service.impl.*.*(..))")

    public void afterexception(){

        logger.info("***************异常通知*****************");

    }

    @After(value ="execution(* com.bdit.Service.impl.*.*(..))")

    public void after(){

        logger.info("***************最终通知*****************");

    }

  1. 启用SpringAOP注解的支持

<!--开启Spring对注解的支持-->

   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

  1. 测试类

package com.bdit;

import com.bdit.Service.IAccountService;

import com.bdit.entify.Account;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

 

//基于纯注解的测试

@RunWith(SpringJUnit4ClassRunner.class)

//指定Spring配置文件的位置

@ContextConfiguration(locations ={"classpath:Spring.xml"})

public class SpringSpp {

   @Autowired  //注入数据

   private IAccountService  iAccountService;

   @Test

    public  void apples(){

       Account  account= new Account();

       account.setZid(1);

       account.setMoney(23232.232);

       account.setUid(3);

         iAccountService.save(account);

   }

}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!