Spring Boot实战笔记(一)-- Spring简介
一、Spring 概述
Spring框架是一个轻量级的企业级开发的一站式解决方案。所谓的解决方案就是可以基于Spring解决所有的Java EE开发的所有问题。
Spring框架主要提供了Ioc(Inversion of Control 控制反转)容器、AOP、数据访问、Web开发、消息、测试等相关技术的支持。
Spring使用简单的POJO(Plain Old Java Object 简单的普通Java对象)来进行企业级开发。每一个被Spring管理的Java的对象都被称为Bean;而Spring提供了一个Ioc容器来初始化对象,解决对象间的依赖管理和对象的使用。
(1)核心容器(Core Container)
Spring-Core:核心工具类,Spring其他模块大量使用Spring-Core;
Spring-Beans:Spring定义Bean的支持;
Spring-Context:运行时Spring容器;
Spring-Context-Support:Spring容器对第三方包的集成支持;
Spring-Expression:使用表达式语言在运行时查询和操作对象;
(2)AOP(Aspect Oriented Programming 面向切面编程)
Spring-AOP:基于代理的AOP支持;
Spring-Aspects:基于AspectJ的AOP支持;
(3)消息(Messaging)
Spring-Messaging:对消息架构和协议的支持。
(4)Web
Spring-Web:提供基础的Web集成功能,在Web项目中提供Spring的容器;
Spring-Webmvc:提供基于Servlet的Spring MVC;
Spring-Socket:提供WebSocket功能;
Spring-Webmvc-Portlet:提供Portlet环境支持;
(5)数据访问/集成(Data Access/Integration)
Spring-JDBC:提供以JDBC访问数据库的支持;
Spring-TX:提供编程式和声明式的事务支持;
Spring-ORM:提供对对象/关系映射技术的支持;
Spring-OXM:提供对对象/xml映射技术的支持;
Spring-JMS:提供对JMS的支持;
二、Spring项目搭建
1.使用IDEA创建Maven项目
File -> New -> Project -> Maven
填写自己的GroupId和ArtifactId后下一步,项目名默认就好,然后创建完成
创建后目录结构如下
修改pom.xml如下:
<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>com.ecworking</groupId>
<artifactId>spring-study</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <name>spring-study</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>3.8.1</junit.version>
<java.version>1.8</java.version>
<spring-context.version>4.1.6.RELEASE</spring-context.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-context.version}</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source> <!-- 源代码使用的开发版本 -->
<target>${java.version}</target> <!-- 需要生成的目标class文件的编译版本 -->
<!-- 一般而言,target与source是保持一致的,但是,有时候为了让程序能在其他版本的jdk中运行(对于低版本目标jdk,源代码中需要没有使用低版本jdk中不支持的语法),会存在target不同于source的情况 -->
</configuration>
</plugin>
</plugins>
</build> </project>
修改完后会自动导入Maven依赖的jar包,依赖树如下:
三、Spring基础配置
Spring框架有四大基本原则:
1.使用POJO进行轻量级和最小侵入式开发;
2.通过依赖注入和基于接口编程实现松耦合;
3.通过AOP和默认习惯进行声明式编程;
4.使用AOP和模板减少模式化代码;
Spring所有的功能设计和实现都是基于此四大原则的。
3.1 依赖注入
我们常说的控制反转IOC和依赖注入DI在Spring环境下是等同的概念,控制反转通过依赖注入实现的。所谓的依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。
依赖注入的主要目的是为了解耦,体现了一种“组合”的概念。如果你希望你的类具备某项功能的时候,是继承一个此功能的父类好呢?还是组合一个此功能的类好?答案是不言而喻的,继承一个父类,子类将与父类耦合,而组合另一个类则使耦合度大大降低。
Spring Ioc容器(ApplicationgContext)负责创建Bean,并通过容器将功能类Bean注入到你需要的功能类中。Spring提供使用xml配置、注解、Java配置、groovy配置实现Bean的创建和注入。
无论是xml配置、注解配置还是Java配置,都被称为配置元数据,所谓元数据即描述数据的数据。元数据本身不具备任何可执行的能力,只能通过外界代码来对这些元数据进行解析后进行一些有意义的操作。Spring容器解析这些配置元数据进行Bean初始化、配置和管理依赖。
声明Bean的注解:
- @Component组件,没有明确的角色。
- @Service在业务逻辑层(service层)使用。
- @Repository在数据访问层(dao层)使用。
- @Controller在展现层(MVC-->Spring MVC)使用。
注入Bean的注解,一般情况下通用:
- @Autowired:Spring提供的注解。
- @Inject:JRS-330提供的注解。
- @Resource:JRS-250提供的注解。
@Autowired、@Inject、@Resource可注解在set方法或者属性上,一般习惯注解在属性上,优点是代码更少、层次更清晰。
接下来演示基于注解Bean的初始化和依赖注入,Spring容器类选用AnnotationConfigApplicationContext。
(1)编写功能类的Bean。
使用@Service注解声明当前FunctionService类是Spring管理的一个Bean。其中,使用@Component、@Service、@Repository和@Controller是等效的,可根据需要选用。
package com.ecworking.service; import org.springframework.stereotype.Service; @Service //使用@Service注解声明当前FunctionService类是Spring管理的一个Bean。其中,使用@Component、@Service、@Repository和@Controller是等效的,可根据需要选用。
public class FunctionService {
public String sayHello(String name){
return name + " Hello!";
}
}
(2)使用功能类Bean。
package com.ecworking.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service //使用@Service注解声明当前UseFunctionService类是Spring管理的一个Bean;
public class UseFunctionService { @Autowired //使用@Autowired将FunctionService的实体Bean注入到UseFunctionService中,让UseFunctionService具备FunctionService的功能,此处使用@Inject注解或者@Resource注解是等效的。
FunctionService functionService; public String sayHello(String name){
return functionService.sayHello(name);
}
}
(3)配置类。
package com.ecworking; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration // 使用@Configuration声明当前类是一个配置类;
@ComponentScan("com.ecworking.service") //使用@ComponentScan,自动扫描包名下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean。
public class Config {
}
(4)运行。
package com.ecworking; import com.ecworking.service.UseFunctionService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App {
public static void main( String[] args ){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); //使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数; UseFunctionService useFuncService = context.getBean(UseFunctionService.class); //获得声明配置的UseFunctionService的Bean。 System.out.println(useFuncService.sayHello("DYP")); context.close();
}
}
运行结果:
3.2 Java配置
Java配置是Spring4.x推荐的配置方式,可以完全代替xml配置;Java配置也是Spring Boot推荐的配置方式。
Java配置通过@Configuration和@Bean来实现的。
- @Configuration声明当前类是一个配置类,相当于一个Spring配置的xml文件。
- @Bean注解在方法上,声明当前方法返回值为一个Bean。
何时使用Java配置或者注解配置呢?我们主要的原则是:全局配置使用Java配置(如数据库相关配置、MVC相关配置),业务Bean的配置使用注解配置(@Component、@Service、@Repository、@Controller)。
(1)编写功能类的Bean。
package com.ecworking.service; //此处没有使用@Service声明Bean
public class FunctionService {
public String sayHello(String name){
return name + " Hello!";
}
}
(2)使用功能类Bean。
package com.ecworking.service; //此处没有使用@Service声明Bean
public class UseFunctionService { // 此处没有@Autowried注解注入Bean
FunctionService functionService; public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
} public String sayHello(String name){
return functionService.sayHello(name);
}
}
(3)配置类。
package com.ecworking; import com.ecworking.service.FunctionService;
import com.ecworking.service.UseFunctionService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 声明当前类只一个配置类,此处没有使用包扫描,是因为所有的Bean都在此类中定义
public class Config { @Bean // 声明当前方法的返回值是一个Bean,Bean的名称是方法名
public FunctionService functionService(){
return new FunctionService();
} @Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
useFunctionService.setFunctionService(functionService()); // 注入FunctionService的Bean的时候直接调用functionService()
return useFunctionService;
}
}
(4)运行。
package com.ecworking; import com.ecworking.service.UseFunctionService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App {
public static void main( String[] args ){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); UseFunctionService useFuncService = context.getBean(UseFunctionService.class); System.out.println(useFuncService.sayHello("DYP")); context.close();
}
}
运行结果:
3.3 AOP
AOP:面向切面编程,相对于OOP面向对象编程。
Spring的AOP的存在是为了解耦。AOP可以让一组类共享相同的行为。在OOP中只能通过继承类和实现接口,来使代码耦合性增强,且类继承只能是单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。
Spring支持AspectJ的注解式切面编程。
1)使用@Aspect声明是一个切面。
2)使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
3)其中@After、@Before、@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around 的参数中调用。
4)其中符合条件的每一个被拦截点为连接点(JoinPoint)。
接下来将演示基于注解拦截、和基于方法规则拦截两种方式,演示一种模拟记录操作的日志系统的实现。其中注解式拦截能够很好的控制要拦截的粒度和获得更丰富的信息,Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)上面都是使用此种方式的拦截。
(1)添加spring aop支持以及 AspectJ依赖
<!-- spring-aop 支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency> <!-- aspectj 支持 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
(2) 编写拦截规则的注解。
package com.ecworking.aop; import java.lang.annotation.*; // 这里讲下注解,注解本身是没有功能的,和xml一样。注解和xml都是一种元数据,元数据即解释数据的数据,这就是所谓的配置。
// 注解的功能来自用这个注解的地方 @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
}
(3)编写使用注解的被拦截类。
package com.ecworking.aop; import org.springframework.stereotype.Service; @Service
public class DemoAnnotationService {
@Action(name = "注解式拦截的add操作")
public void add(){}
}
(4)编写使用方法规则被拦截类。
package com.ecworking.aop; import org.springframework.stereotype.Service; @Service
public class DemoMethodService {
public void add(){}
}
(5)编写切面。
package com.ecworking.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 // 通过 @Aspect 注解声明一个切面。
@Component // 通过 @Component 让此切面成为Spring管理的Bean。
public class LogAspect { @Pointcut("@annotation(com.ecworking.aop.Action)") // 通过 PonintCut 注解声明切点。
public void annotationPointCut(){
System.out.println("自动注入的切点");
} @After("annotationPointCut()") // 通过 @After 注解声明一个建言,并使用 @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()); // 通过反射可获得注解上的属性,然后做日志记录相关操作,下面的相同。
} /**
* 定义切入点表达式 execution (* com.sample.service.impl..*.*(..))
* execution()是最常用的切点函数,其语法如下所示:
* 整个表达式可以分为五个部分:
* 1、execution(): 表达式主体。
* 2、第一个*号:表示返回类型,*号表示所有的类型。后面要加空格和包名隔开。
* 3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
* 4、第二个*号:表示类名,*号表示所有的类。
* 5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数
*/
@Before("execution(* com.ecworking.aop.DemoMethodService.*(..))") // 通过 @Before 注解声明一个建言,此建言直接使用拦截规则作为参数。
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法式拦截:" + method.getName());
}
}
(6)配置类。
package com.ecworking.aop; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("com.ecworking.aop")
@EnableAspectJAutoProxy // 使用@EnableAspectJAutoProxy 注解开启Spring对AspectJ代理的支持。
public class AopConfig {
}
(7)运行。
package com.ecworking.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();
}
}
运行结果:
Spring Boot实战笔记(一)-- Spring简介的更多相关文章
- Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...
- JavaEE开发的颠覆者 Spring Boot实战--笔记
1.Spring boot的三种启动模式 Spring 的问题 Spring boot的特点,没有特别的地方 1.Spring 基础 PS:关于spring配置 PS: 现在都已经使用 java配置, ...
- spring boot 实战笔记(一)
spring 概述: Bean :每一个被 Spring 管理的 JAVA对象,都称之为 Bean.Spring提供一个IoC容器来初始化对象,负责创建Bean, 解决对象之间的依赖管理和对象的使用. ...
- Spring Boot 学习笔记 - 认识Spring Boot框架
因各种原因,.NET前端工程师重新接触JAVA,真是向全栈的路上又迈出了无奈的一步. 下面正文: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初 ...
- Spring Boot实战笔记(九)-- Spring高级话题(组合注解与元注解)
一.组合注解与元注解 从Spring 2开始,为了响应JDK 1.5推出的注解功能,Spring开始大量加入注解来替代xml配置.Spring的注解主要用来配置注入Bean,切面相关配置(@Trans ...
- Spring Boot实战笔记(七)-- Spring高级话题(计划任务)
一.计划任务 从Spring3.1开始,计划任务在Spring中的实现变得异常的简单.首先通过在配置类注解@EnableScheduling来开启对计划任务的支持,然后在执行计划任务的方法上注解@Sc ...
- Spring Boot实战笔记(五)-- Spring高级话题(Spring Aware)
一.Spring Aware Spring 依赖注入的最大亮点就是你所有的 Bean 对 Spring容器的存在是没有意识的.即你可以将你的容器替换成其他的容器,如Google Guice,这时 Be ...
- Spring Boot实战笔记(四)-- Spring常用配置(事件Application Event)
一.事件(Application Event) Spring的事件为Bean和Bean之间的消息通信提供了支持.当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时我们就需要 ...
- Spring Boot实战笔记(三)-- Spring常用配置(Bean的初始化和销毁、Profile)
一.Bean的初始化和销毁 在我们的实际开发的时候,经常会遇到Bean在使用之前或之后做些必要的操作,Spring对Bean的生命周期操作提供了支持.在使用Java配置和注解配置下提供如下两种方式: ...
随机推荐
- spring揭秘 读书笔记 一 IoC初探
本文是王福强所著<<spring揭秘>>一书的读书笔记 ioc的基本概念 一个例子 我们看下面这个类,getAndPersistNews方法干了四件事 1 通过newsList ...
- mysql进阶(十九)SQL语句如何精准查找某一时间段的数据
SQL语句如何精准查找某一时间段的数据 在项目开发过程中,自己需要查询出一定时间段内的交易.故需要在sql查询语句中加入日期时间要素,sql语句如何实现? SELECT * FROM lmapp.lm ...
- Java进阶(十八)Java实现定时器(Timer)
Java实现定时器(Timer) 绪 在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类.java.u ...
- android 开发Handler源码剖析
Android的消息机制主要是Handler的运行机制,而讲Handler的机制,又需要和MessageQueue和Looper结合.MessageQueue中文意思是消息队列,虽说叫队列,但是其内部 ...
- LIRe 源代码分析 2:基本接口(DocumentBuilder)
===================================================== LIRe源代码分析系列文章列表: LIRe 源代码分析 1:整体结构 LIRe 源代码分析 ...
- "《算法导论》之‘线性表’":基于动态分配的数组的顺序表
我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变.如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的.基于动态分 ...
- android 防止反编译的若干方法
第一种方式:混淆策略 混淆策略是每个应用必须增加的一种防护策略,同时他不仅是为了防护,也是为了减小应用安装包的大小,所以他是每个应用发版之前必须要添加的一项功能,现在混淆策略一般有两种: 对代码的混淆 ...
- CentOS服务器下JavaEE环境搭建指南(远程桌面+JDK+Tomcat+MySQL)
--------------------------------------------------------------------------------1 系统设置:1.1 远程桌面设置:通过 ...
- 是我out了,c11标准出炉鸟
gcc -std=c11 -Wall -O3 -g0 -s -o x.c x 或者 clang -std=c11 -Wall -O3 -g0 -s -o x.c x 来吧! 我是有多无聊啊 测试代码: ...
- linux下64位汇编的系统调用(5)
看到这里大家都基本知道了如何进行linux下的汇编系统调用:不过有些童鞋可能会问:那些C库中函数里为我们解决的额外汇编代码你是怎么知道的? 好吧,我承认:我是通过逆向知道的,这貌似有点犯规的嫌疑- 比 ...