Spring基础

Spring基础,主要涉及maven的介绍使用,控制反转和依赖注入以及关于(AOP)面向切面编程。

Spring配置方式

  1. xml配置
  2. 注解配置
  3. Java配置

Maven简介

​ maven是一个软件项目管理工具。基于项目管理对象模型的概念,可用来管理项目的依赖、编译、文档等信息。

​ 在maven中管理依赖时只需要在配置文件pom.xml中按下面的形式添加就好了。

1
2
3
4
5
<dependency>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
</dependency>

​ 添加完成以后maven就会通过互联网在maven中心库下载相关的依赖包到.m2目录下,也是你的本地maven库,如果中心库没有你需要的jar包,需要自己使用maven命令导入到本地maven库。

依赖注入

​ 在Spring的概念下,控制翻转和依赖注入是等同的概念,控制翻转是通过依赖注入实现的。依赖注入指容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。

​ 依赖注入的目的是为了解耦,使用“组合”的概念降低类之间的耦合度。Spring IoC容器负责创建Bean,并且通过容器将功能类Bean注入到需要的Bean中。Spring 提供使用xml、注解、Java配置、groovy配置实现Bean的创建和注入。

声明Bean的注解有:

  • @Component 组件,没有明确的角色
  • @Service 在业务逻辑层(service层)使用
  • @Respository 在数据访问层(dao层)使用
  • @Controller 在展现层(MVC - SpringMVC)使用

注入Bean的注解:

  • @Autowired:Spring提供的注解
  • @Inject:JSR-330提供的注解
  • @Resource:JSR-250提供的注解

注入Bean的注解可以用在set方法上或者属性上。

配置

​ Java配置是现在推荐的方式,主要通过@Configuration 和@Bean 来实现

  • @Configuration 声明当前类是一个配置类,相当于一个Spring配置的xml文件。
  • @Bean 注解在方法上,声明当前方法的返回值为一个Bean。

遵循的基本原则是:全局配置使用Java配置(如数据库相关配置、maven相关配置),业务Bean的配置使用注解配置。

AOP:面向切面编程

​ Spring的AOP 存在的目的就是为了解耦。可以让一组类共享相同的行为。Spring 支持AspectJ 的注解式切面编程。

  • 使用@Aspect 声明是一个切面。
  • 使用@After 、@Before 、@Around 定义建言(advice),可直接将拦截规则(切点)作为参数。
  • 其中@After 、@Before 、@Around 参数的拦截规则作为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After 、@Before 、@Around 的参数中调用。
  • 其中符合条件的每一个被拦截处为连接点(JoinPoint)。

下面给出一个AOP的 demo:

​ 首先在pom.xml中添加相关的依赖,相应信息可以在maven仓库中查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- aspectj支持 -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>

编写拦截规则的注解:

1
2
3
4
5
6
7
8
9
10
package aop;

import java.lang.annotation.*;

@Target(ElementType.METHOD) //说明该注解的作用目标是方法
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented //定义为Bean
public @interface Action {
String name();
}

编写使用注解的被拦截器:

1
2
3
4
5
6
7
8
package aop;

import org.springframework.stereotype.Service;
@Service //定义为Bean
public class DemoAnnotationService {
@Action(name="注解式拦截的add操作")
public void add(){}
}

编写使用方法规则被拦截器:

1
2
3
4
5
6
7
package aop;

import org.springframework.stereotype.Service;
@Service
public class DemoMethodService {
public void add(){}
}

编写切面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package aop;

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.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

@Aspect //该注解声明一个切面
@Component //定义为Bean
public class LogAspect {
@Pointcut("@annotation(aop.Action)") //声明一个切点
public void annotationPointCut(){}

@After("annotationPointCut()") //声明一个建言,并使用@Pointcut定义的切点
public void after(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截 " + action.name());
}

@Before("execution(* aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法式拦截 " + method.getName());
}
}

配置类:

1
2
3
4
5
6
7
8
9
10
package aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("aop")
@EnableAspectJAutoProxy //开启Spring对AspectJ的支持
public class AopConfig {
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);

demoAnnotationService.add();
demoMethodService.add();

context.close();
}
}

输出结果为:
注解式拦截 注解式拦截的add操作
方法式拦截 add
0%