Spring
-
简介
1.Spring 是一个开源框架 2.Spring 是为了简化企业级应用开发而生 3.Spring 是java/javaee 一站式框架
-
两大核心
-
Spring IOC (DI 也称依赖注入)
基本配置:
-
导架包(所需架包):
<spring.version>4.3.18.RELEASE</spring.version> 使用来统一版本
版本统一很重要,不然会报错
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <spring.version>4.3.18.RELEASE</spring.version> </properties>
${spring.version}是占位符
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${spring.version}</version> </dependency>
下面的是用来记录日志的
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
配置spring
-
创建接口
package com.imooc; public interface imp { public void Demo(); }
-
实现类
package com.imooc; public class SpringDemo1 implements imp { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void Demo() { System.out.println("hello" +name); } }
-
配置spring 配置文件(spring-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="text" class="com.imooc.SpringDemo1"> <!--设置依赖注入--> <property name="name" value="张三"></property> </bean> </beans
-
测试
package com.imooc; public class SpringDemo1 implements imp { @Test public void Demo() { System.out.println("hello"+name); } }
-
测试结果
-
-
-
Spring Aop(面向切面编程)
为什么要使用aop
问题:
•代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀**.** 每个****方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
•代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化**,** 必须修改所有模块.
那什么是面向切面编程呢?在运行方法时,动态的将代码切入到类的指定方法、指定位置上的编程思想就是面向切面编程
-
Aop的术语
-
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象 加强(Advice): 切面必须要完成的工作 目标(Target): 被加强的对象 代理(Proxy): 向目标对象应用加强之后创建的对象 连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置 切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
-
用 AspectJ注解声明切面
- 要在 Spring中声明** AspectJ 切面**,** 只需要在IOC** 容器中将切面声明为Bean** 实例.
- •在 AspectJ 注解中**,** 切面只是一个带有@Aspect** 注解的 Java类**.
-
AspectJ 支持5种类型的加强注解:
-
–@Before: 前置加强,在方法执行之前执行
-
–**@After****?*后置加强,在方法执行之后执行
-
@AfterRunning: 返回加强,在方法返回结果之后执行
-
–@AfterThrowing: 异常加强,在方法抛出异常之后
-
–@Around: 环绕加强,围绕着方法执行
例如:
用Aspect标识这个类是个切面
-
-
-
如何访问当前连接点的细节
可以在加强方法中声明一个类型为 JoinPoint的参数.然后就能访问链接细节. 如方法名称和参 数值.
例如:
前置加强
标识这个方法是个前置加强, 切点表达式表示执行任意类的任意方法. 第
一个 * 代表匹配任意修饰符及任意返回值, 第二个 * 代表任意类的对象,
第三个 * 代表任意方法, 参数列表中的 … 匹配任意数量的参数
后置加强(注:一个切面可以有多个加强)
返回加强
•无论连接点是正常返回还是抛出异常**,** 后置加强都会执行.
如果只想在连接点返回的时候记录日志**,** 应使用返回加强代替后置加强.
在返回加强中访问返回值:
在返回加强中, 只要将returning属性添加到@AfterReturning注解中,就可以访问连接点的返回值.
该属性的值即为用来传入返回值的参数名称,名字需同名
异常加强(可以捕获异常)
环绕加强
- 环绕加强是所有加强类型中功能最为强大的,能够全面地控制连接点.甚至可以控制是否执行连接点.
- 对于环绕加强来说**,** 连接点的参数类型必须是****ProceedingJoinPoint. 它是 JoinPoint
的子接口,允许控制何时执行**,** 是否执行连接点. - 在环绕加强中需要明确调用 ProceedingJoinPoint 的****proceed() 方法来执行被代理的方法**.** 如果忘记这样做就会导致加强被执行了**,** 但目标方法没有被执行.
- 注意: 环绕通知的方法需要返回目标方法执行之后的结果**,** 即调用
joinPoint.proceed**();** 的返回值**,** 否则会出现空指针异常