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配置和注解配置下提供如下两种方式: ...
随机推荐
- Activity堆栈管理
task就好像是能包含很多activity的栈. 默认情况下,一个activity启动另外一个activity时,两个activity是放在同一个task栈中的,第二个activity压入第一个 ac ...
- Linux学习笔记 --iptables防火墙配置
iptables防火墙配置 一.防火墙简介 1.功能: 1)通过源端口,源IP地址,源MAC地址,包中特定标记和目标端口,IP,MAC来确定数据包是否可以通过防火墙 2)分割内网和外网[附带的路由器的 ...
- LIRe提供的图像检索算法的速度
本文翻译了LIRe的作者Mathias Lux发表的论文<LIRe: Lucene Image Retrieval - An Extensible Java CBIR Library>.主 ...
- STL算法设计理念 - 谓词,一元谓词demo
谓词: 一元函数对象:函数参数1个: 二元函数对象:函数参数2个: 一元谓词 函数参数1个,函数返回值是bool类型,可以作为一个判断式 谓词可以使一个仿函数,也可以是一个回调函数. demo 一元谓 ...
- Microsoft Dynamics CRM 2011 JS操作集锦
1.Xrm.Page.context 用户ID:getUserId() 用户角色:getUserRoles() 用户语言:getUserLcid() 组织名称:getOrgUniqueName() 组 ...
- Cocos2D粒子发射器的纹理
每个例子发射器只能使用单个纹理发射粒子. 如果你需要在相同粒子效果中组合多重纹理,你将不得不创建多重的发射器节点并且决定谁的粒子将在其它粒子之上或之下显示.
- 说说struts2中拦截器的请求流程一(模拟大致流程)
本文可作为北京尚学堂struts2课程的学习笔记. 首先 什么是拦截器?拦截器能干什么? 拦截器,顾名思义就是拦截对象然后做操作的东西,至于是拦截谁?那自然是拦截action了.能做什么操作呢?你想让 ...
- 如何写好一个UITableView(完整版)
本文是直播分享的简单文字整理,直播共分为上.下两部分.第一部分:优酷 Or YouTube,第二部分:优酷 Demo 地址:KtTableView 如果你觉得UITableViewDelegate和U ...
- Android Data Binding代码实践(告别findViewById)(四)
Data Binding实战(一) Data Binding语法解析(二) Data Binding高级用法(三) 好了,继前三篇学习了Data Binding之后,我们可以发现它的强大之处有这么几点 ...
- iOS开发小技巧总结
一.NSLog的使用 NSLog在调试的时候,屡试不爽,可是在项目中用的太多,其实是会影响程序性能的,而且程序在非调试模式下也看不到打印,多浪费资源呢?如果程序中使用的太多,发布前删除又是一个麻烦事, ...