1.1Spring概述
1.1.1 spring简史
第一阶段:xml配置(spring 1.x时代)
第二阶段:注解配置(spring 2.x时代)
第三阶段:java配置(spring 3.x以后)
1.1.2 spring概述
spring框架主要提供了IoC容器、AOP、数据访问、Web开发、消息、测试等相关技术的支持。
spring使用POJO,每个被spring管理的java对象都称为Bean,而spring提供了一个IOC容器来初始化对象,解决对象之间的依赖管理和对象的使用。
1. Spring的模块
spring是模块化的,即可以只是用你需要的spring模块。
(1)核心容器core container
(2)AOP
(3)消息
(4)Web
(5)数据访问/集成
2. Spring的生态
spring boot:使用默认开发配置来实现快速开发
spring XD: 用来简化大数据应用开发
Spring Cloud:为分布式系统开发提供工具集。
Spring Data:对主流的关系型和NoSQL数据库的支持。
Spring Security:通过认证和授权保护应用。
1.2 Spring项目搭建
项目构建工具:Ant、Maven、Gradle
1.2.1 Maven的pom.xml
常用元素:
-
dependencies
此元素包含多个项目依赖需要使用的<dependency></dependency>
。 -
dependency
内部通过
groupId 组织的唯一标识
artifactId 项目的唯一标识
version 项目的版本
确定唯一的依赖 -
变量定义
可定义变量在dependency中引用
<properties>
<spring-framework.version>4.1.5.RELEASE</spring-framework.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
- 编译插件
Maven提供了编译插件,可在编译插件中涉及Java的编译级别
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
1.2.2 Maven的运作方式
Maven会自动根据dependency中的依赖配置,直接通过互联网在Maven中心库下载相关依赖包到.m2目录下,.m2目录下是你本地Maven库。
http://mvnrepository.com
1.3 Spring基础配置
Spring框架本身有四大原则:
1)使用POJO进行轻量级和最小侵入式开发。
2)通过依赖注入和基于接口编程实现松耦合。
3)通过AOP和默认习惯进行声明式编程。
4)使用AOP和模板(template)减少模式化代码。
1.3.1依赖注入
控制反转(IoC)和依赖注入(DI)在Spring中等同的,控制反转实现依赖注入的实现。
依赖注入的目的:主要是为了解耦,体现一种组合的理念。
Spring IoC容器:负责创建Bean,并通过容器将功能类Bean注入到需要的Bean中。Spring提供使用xml,注解,java配置,groovy配置实现Bean的创建和注入。
申明Bean的注解:
@Component 组件,没用明确的角色
@Service 在业务逻辑层(service层)使用
@Repository 在数据访问层(dao层)使用
@Controller 在展现层(MVC-spring mvc)使用
注入Bean的注解,一般情况下通用:
@Autowired Spring提供的注解
@Inject JSR-330提供的注解
@Resource JSR-250提供的注解
1.3.2java配置
Java配置是通过@Configuration和@Bean来实现的。
@Configuration声明当前类是一个配置类,相当于一个Spring配置的xml文件。
@Bean注解在方法上,声明当前方法的返回值为一个Bean。
声明组件方式示例
(1)编写功能类的Bean
@Service //1
public class FunctionService {
public String sayHello(String word){
return "Hello " + word +" !";
}
}
代码解释:
使用@Service注解声明当前FunctionService类是Spring管理的一个Bean。
(2)使用功能类的Bean
@Service //1
public class UseFunctionService {
@Autowired //2
FunctionService functionService;
public String SayHello(String word){
return functionService.sayHello(word);
}
}
使用@Service注解声明当前UseFunctionService类是Spring管理的一个Bean。
使用@Autowired将FunctionService的实体Bean注入到UseFunctionService中,让UseFunctionService具备FunctionService的功能
(3)配置类
@Configuration //1
@ComponentScan("com.wisely.highlight_spring4.ch1.di") //2
public class DiConfig {
}
@Configuration声明当前类是一个配置类
使用@ComponentScan,自动扫描包名下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean.
(4)运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class); //1
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class); //2
System.out.println(useFunctionService.SayHello("di"));
context.close();
}
}
使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数;
获得声明配置的UseFunctionService的Bean
java配置方式示例
(1)编写功能类的Bean
public class FunctionService {
public String sayHello(String word){
return "Hello " + word +" !";
}
}
此处没有使用@Service声明Bean
(2)使用功能类的Bean
public class UseFunctionService {
//2
FunctionService functionService;
public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
}
public String SayHello(String word){
return functionService.sayHello(word);
}
}
此处没有使用@Service声明Bean。
此处没有使用@Autowired注解注入Bean。
(3)配置类
@Configuration //1
public class JavaConfig {
@Bean //2
public FunctionService functionService(){
return new FunctionService();
}
@Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
useFunctionService.setFunctionService(functionService());//3
return useFunctionService;
}
// @Bean
// public UseFunctionService useFunctionService(FunctionService functionService){ //4
// UseFunctionService useFunctionService = new UseFunctionService();
// useFunctionService.setFunctionService(functionService);
// return useFunctionService;
// }
}
使用@Configuration注解表明当前类是一个配置类,这意味着这个类里可能有0个或者多个@Bean注解,此处没有使用包扫描,是因为所有的Bean都在此类中定义了。
使用@Bean注解声明当前方法FunctionService的返回值是一个Bean,Bean的名称是方法名。
注入FunctionService的Bean时候直接调用functionService()
(4)运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
System.out.println(useFunctionService.SayHello("java config"));
context.close();
}
}
1.3.3 AOP
AOP:面向切面编程,相对于OOP面向对象编程。
Spring支持AspectJ的注解式切面编程
(1)使用@Aspect声明是一个切面。
(2)使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
(3)其中@After、@Before、@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。
(4)其中符合条件的每一个被拦截处为连接点(JoinPoint)。
基于注解拦截方式、基于方法规则拦截方式示例
(1)添加mvn依赖
(2)编写拦截规则的注解
package com.wisely.highlight_spring4.ch1.aop;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
}
这里讲下注解,注解本身是没有功能的,就和xml一样。注解和xml都是一种元数据,元数据即解释数据的数据,这就是所谓配置。
注解的功能来自用这个注解的地方。
(3)编写使用注解的被拦截类
package com.wisely.highlight_spring4.ch1.aop;
@Service
public class DemoAnnotationService {
@Action(name="注解式拦截的add操作")
public void add(){}
}
(4)编写使用方法规则被拦截类
package com.wisely.highlight_spring4.ch1.aop;
@Service
public class DemoMethodService {
public void add(){}
}
(5)编写切面
package com.wisely.highlight_spring4.ch1.aop;
@Aspect //1
@Component //2
public class LogAspect {
@Pointcut("@annotation(com.wisely.highlight_spring4.ch1.aop.Action)") //3
public void annotationPointCut(){};
@After("annotationPointCut()") //4
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()); //5
}
@Before("execution(* com.wisely.highlight_spring4.ch1.aop.DemoMethodService.*(..))") //6
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
}
①通过@Aspect注解声明一个切面。
②通过@Component让此切面成为Spring容器管理的Bean。
③通过@PointCut注解声明切点。
④通过@After注解声明一个建言,并使用@PointCut定义的切点。
⑤通过反射可获得注解上的属性,然后做日志记录相关的操作,下面的相同。
⑥通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数。
(6)配置类
package com.wisely.highlight_spring4.ch1.aop;
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch1.aop")
@EnableAspectJAutoProxy //1
public class AopConfig {
}
①使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持。
(7)运行
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); //1
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
demoAnnotationService.add();
demoMethodService.add();
context.close();
}
}