2018暑期充实日记(1)Spring-AOP

2018暑期已经是大三了,就想着把平时零散学习或者没时间深究的问题好好弄一下,正好在找实习工作,一举两得。

Spring框架

轻量级的框架,我在阅读许多的博客文章和技术文之后得到两个重点。(当然还有其他特别多的功能,但是初学以及应用中的话要优先学习这两个,服务于具体项目)

1.AOP
2.DI

AOP是个什么鬼鬼呢?

简单点来说AOP(面向切面编程),就是业务开发者无需注意具体业务之外的流程,包括日志记录,权限授权等问题。比如我实现支付宝pay支付功能,我不需要知道这个人密码啊,支付记录的写入啊等等,我需要做的就是银行扣款这个具体业务的实现。简化了程序开发,提高开发效率。

Spring版本迭代,AOP的实现方式也不大同(虽然结果是一样的),就我现在了解到的情况,共有三个。

1.XML配置实现AOP
2.注解配置AOP(Aspectj)

我先来新建一个项目搭载我的spring框架(空口吹逼最为致命)

idea添加maven开发能力,之后上网查一下spring的dependecy。

现在是完成的样子。(Spring本身没有日志记录,所以导入一个log4j,或者commons来记录状态,不然具体情况无法分析)

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>spring-aop</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.3.0.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
            <version>4.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>
    </dependencies>
</project>

左侧是项目结构,注意actioncontext.xml,这里是aop.xml,需要放在resource里面,下面是测试代码。
package com.hjj.source.math;

public class math1 {
    public double add(double n1,double n2){
        double result=n1+n2;
        System.out.println(n1+"+"+n2+"="+result);
        return result;
    }

    //减
    public double sub(double n1,double n2){
        double result=n1-n2;
        System.out.println(n1+"-"+n2+"="+result);
        return result;
    }

    //乘
    public double mut(double n1,double n2){
        double result=n1*n2;
        System.out.println(n1+"X"+n2+"="+result);
        return result;
    }

    //除
    public double div(double n1,double n2){
        double result=n1/n2;
        System.out.println(n1+"/"+n2+"="+result);
        return result;
    }
}

这是对实数的基本运算,可以看到这里是只关注了具体的实现逻辑,而我们的日志记录并没有写入其中,而是新建了一个advice。

1.XML配置实现AOP

package com.hjj.source.math;
import org.aspectj.lang.JoinPoint;
public class Advices {
    public void before(JoinPoint jp){
        System.out.println("----------运算开始----------");
//        获取方法名
        System.out.println(jp.getSignature().getName());
    }

    public void after(JoinPoint jp){
        System.out.println("----------运算结束----------");
    }
}
JoinPoint是具体业务实现的时候的方法(只能是以方法为对象)。
Spring的AOP机制就是针对每个业务类,额外添加能力,使开发者在不关心也不用修改代码的情况下,添加系统级别的功能。因此一定是以方法为对象的。即每个方法都是Joinpoint,但是实际应用中可能只需要对部分方法进行AOP。
Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式.
这里又要学到切入点表达式(东西太多了,放新一篇里面说,这篇只关注如何实现一个AOP)。

同时又要学到after,before,around等通知类型。


aop.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-4.3.xsd">
    <!-- 被代理对象 -->
    <bean id="math" class="com.hjj.source.math.math1"></bean>

    <!-- 通知 -->
    <bean id="advices" class="com.hjj.source.math.Advices"></bean>

    <!-- aop配置 -->
    <aop:config proxy-target-class="true">
        <!--切面 -->
        <aop:aspect ref="advices">
            <!-- 切点 -->
            <aop:pointcut expression="execution(* com.hjj.source.math.math1.*(..))" id="pointcut1"/>
            <!--连接通知方法与切点 -->
            <aop:before method="before" pointcut-ref="pointcut1"/>
            <aop:after method="after" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>
</beans>
test.java
import com.hjj.source.math.math1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");
        math1 math = (math1) ctx.getBean("math");
        double n1 = 12.34, n2 = 23.45;
        math.add(n1, n2);
        math.sub(n1, n2);
        math.mut(n1, n2);
        math.div(n1, n2);
    }

}

result

----------运算开始----------
add
12.34+23.45=35.79
----------运算结束----------
----------运算开始----------
sub
12.34-23.45=-11.11
----------运算结束----------
----------运算开始----------
mut
12.34X23.45=289.373
----------运算结束----------
----------运算开始----------
div
12.34/23.45=0.5262260127931769
----------运算结束----------

2.注解配置AOP

XML配置好处是集中的书写了项目的切面,对阅读整个程序的框架的时候比较清晰直观,但就我的感受来说,很多时候这一点并不是需要关心的,因此简化了书写步骤,在code上直接添加注释,可能来的更为简单与方便。

@Servcie,@Controller,@Repository,@Component

都是Spring对于MVC的注解,代替了在xml中的配置。

service一般标注在service层的bean上,controller标注在控制层,Repository标注在view层,component通用。

@Service("math")
public class math1 {

对于advice用注解改写

@Component
@Aspect
切面的固定写法
package com.hjj.source.math;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class Advices {
    @Before("execution(* com.hjj.source.math.math1.*(..))")
    public void before(JoinPoint jp){
        System.out.println("----------运算开始----------");
//        获取方法名
        System.out.println(jp.getSignature().getName());
    }
    @After("execution(* com.hjj.source.math.math1.*(..))")
    public void after(JoinPoint jp){
        System.out.println("----------运算结束----------");
    }
}

简单完成了Spring中AOP功能,后续部分晚上研究,晚点再传一篇。(包括看到的Aspectj注解以及多种通知)






猜你喜欢

转载自blog.csdn.net/weixin_40553838/article/details/80745946