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>
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("----------运算结束----------"); } }
同时又要学到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注解以及多种通知)