title: Spring Boot实战学习笔记1
tags:Spring Boot实战
摘要
本文为学习Spring Boot实战的学习笔记,学习了一遍,但是好记性不如烂笔头,所以文章记录下来。图书购买地址为: https://item.jd.com/11894632.html.
1.Spring 基础
1.1 Spring 主要模块
1.1.1 核心容器(Core Container)
Spring-Core:核心工具类,Spring其它模块大量使用Spring-Core
Spring-Beans:Spring定义的Bean的支持
Spring-Context:运行时Spring容器
Spring-Context-Support:Spring容器对第三方包的集成支持
Spring-Expression:使用表达式语言在运行是查询和操作对象
1.1.2 AOP
Spring-AOP:基于代理的AOP支持
Spring-Aspects:基于AspectJ的支持.
1.1.3 消息(Messaging)
Spring-Messageing:对消息架构和协议的支持
1.1.4 Web
Spring-Web:提供基础的Web集成的功能,在Web项目中提供Spring的容器
Spring-Webmvc:提供基于Servlet的Spring MVC
Spring-WebSocket:提供WebSocket功能
Spring-Webmvc-Portlet:提供portlet环境支持.
1.1.5 数据访问/集成(Data Access/Integration)
Spring-JDBC: 提供以 JDBC访间数据库的支持
Spnng-TX: 提供编程式和声明式的事务支持
Spnng-0RM: 提供对对象/关系映射技术的支持
Spring-0XM:提供对对象/xml映射技术的支持
Spring-JMS: 提供对 JMS的支持。
1.2 Spring 主要生态
1.3 Spring基础配置
四大原则:
- 使用POJO进行轻量级和最小侵入式开发
- 通过依赖注入和基于接口编程实现松耦合
- 通过AOP和默认习惯进行声明式编程
- 使用AOP和模板(Template)减少模块化代码
Spring所有功能的设计和实现都是基于以上四大原则的.
1.3.1 IOC
控制反转: (IOC-Inversion of Control)
依赖注入: (DI-dependency injection)
在Spring 环境下是等同的,控制翻转是通过依赖注入实现的. 依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖.
Spring Ioc容器(ApplicationContext)负责创建 Bean,并通过容器精功能类 Bean注入到你需要的 Bean中。 spring提供使用 xml、注解、 Java配置、 groovy配置实现 Bean的创建和注入。
元数据: 包括 xml配置、注解配置和Java配置. 元数据本身不具备住何可执行的能力, 只能通过外界代码来对这些元数据行解析后通行一些有意义操作。Spring容器解析这些配置元数据进行 Bean初始化、配置和管理依赖。
声明 Bean的注解:
o @Component组件,没有明确的角色。
o @service在业务逻輯层( service层)使用。
o @Repository 在数据访问层( dao层)使用 。
o @controller在展现层( MVC→Sprmg MVC)使用 。
o @Component Spring容器管理的Bean。
注入 Bean的注解, 一般情况下通用
o @Autowired: Spring提供的注解。
o @Inject: JSR-330提供的注解。
o @Resource: JSR-250提供的注解。
o @EnableAspectJAutoProxy: 注解开启Spring对AspectJ的支持.
常用注解举例
o @Configuration:表明当前类是一个配置类,这个意味着这个类里可能有0个或多个@Bean注解.
1.3.2 AOP
**AOP:**面向切面编程,相对于OOP面向对象编程.
AOP的目的是解耦,AOP让一组类共享相同的行为。
在OOP中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足.
Spring 支持AspectJ的注解切面编程.
- o @AspectJ的注解式切面编程
- o @After,@Before,@Around定义建言(Advice),可直接将拦截规则(切点,PointCut)作为参数。
- o @PointCut 拦截规则为切点(PointCut),定义拦截规则。
- JoinPoint: 连接点,符合条件的每一个拦截处.
AOP
<!-- spring aop支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- aspectj支持 -->
//注意,由于pom标准写法占用个篇幅,改用gradle写法.要要代码时修改即可.或查看本书完整代码.
org.aspectj:aspectjrt:1.8.6
org.aspectj:aspectjweaver:1.8.5
源码下载地址
http://www.broadview.com.cn/book/472
http://www.broadview.com.cn/file/resource/061078061207186156162159222041137008231100137136#
2.Spring 常用配置
2.1 Bean的Scope
Scope描述的是Srping 容器如何新建Bean的实例的.Spring的Scope有:
- 1)Singleton : 一个Spring 容器中只有一个Bean的实例.此为Spring默认配置,全部容器共享一个实例.
- 2)Prototype : 每次调用新建一个Bean的实例.
- 3)Request : 每一个Http的Request新建一个Bean实例.
- 4)Session : 每一个http的Session新建一个Bean实例.
- 5)GlobalSession:每一个global http session新建一个bean(只在portal中有用)
- 6)StepScope : 只在Spring Batch中使用.
写法如下:
@Service
@Scope("prototype")
public class DemoPrototypeService{
}
2.2 EL和资源调用
配置文件:test.properties
book.author=wangyunfei
book.name=spring boot
// 1)普通字符串
@Value("其它类的属性")
private String another;
//2)操作系统属性
@Value("#{systemProperties['os.name']}")
private String osName;
//3)注入表达式结果
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
//4)注入其它Bean结果
@Value("#{demoService.another}")
private String fromAnother;
//5)注入文件资源
@Value("classpath:com/wisely/highlight_spring4/ch2/el/test.txt")
private Resource testFile;
//6)注入网址资源
@Value("http://www.baidu.com")
private Resource testUrl;
//7)注入配置文件,注意这里是$不是#.
@Value("${book.name}")
private String bookName;
//8)标志配置类
@Configuration //通过该注解来表明该类是一个Spring的配置,相当于一个xml文件
//9)标志Bean
@Bean //作用于方法上,相当于xml配置中的<bean>
//扫描配置路径
@ComponentScan(basePackages = "com.wisely.springboot.javaconfig") //配置扫描包
//读取配置文件
@PropertySource(value= {"classpath:jdbc.properties,classpath:jdbc.properties2"})
2.3 Bean的初始化和销毁
在Bean的使用之前或使用之后做些必要的操作,Spring对Bean的生命周期操作也提供了支持.
-
- java配置方式
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch2.prepost")
public class PrePostConfig {
//init->构造之后,destroy->Bean销毁之前
@Bean(initMethod="init",destroyMethod="destroy") //1
BeanWayService beanWayService(){
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService(){
return new JSR250WayService();
}
}
public class BeanWayService {
public void init(){
System.out.println("@Bean-init-method");
}
public BeanWayService() {
super();
System.out.println("初始化构造函数-BeanWayService");
}
public void destroy(){
System.out.println("@Bean-destory-method");
}
}
//highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch2/prepost/BeanWayService.java
///highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch2/prepost/PrePostConfig.java
-
- 注解方式
//支持JSR250
javax.annotation:jsr250-api:1.0
//放在方法上
@PostConstruct //在构造函数之后执行
@PreDestroy //在Bean销毁之前执行
public class JSR250WayService {
@PostConstruct //1
public void init(){
System.out.println("jsr250-init-method");
}
public JSR250WayService() {
super();
System.out.println("初始化构造函数-JSR250WayService");
}
@PreDestroy //2
public void destroy(){
System.out.println("jsr250-destory-method");
}
}
//highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch2/prepost/JSR250WayService.java
-
- 测试执行用类
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(PrePostConfig.class);
BeanWayService beanWayService = context.getBean(BeanWayService.class);
JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
context.close();
}
}
2.4 Profile
Profile为在不同环境下的使用不同的配置.
-
- Environment中的ActiveProfiles.然后用@profiles注解类或方法.
@Configuration
public class ProfileConfig {
@Bean
@Profile("dev")//配置为dev时走这里
public DemoBean devDemoBean() {
return new DemoBean("from development profile");
}
@Bean
@Profile("prod") //配置为prod时走这里
public DemoBean prodDemoBean() {
return new DemoBean("from production profile");
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("dev"); //1设置profile的值
context.register(ProfileConfig.class);//2注册bean
context.refresh(); //3刷新容器
DemoBean demoBean = context.getBean(DemoBean.class);
System.out.println(demoBean.getContent());
context.close();
}
}
//highlight_spring4/src/main/java/ch2/profile/ProfileConfig.java
//highlight_spring4/src/main/java/ch2/profile/Main.java
-
- jvm中的spring.profiles.active
//start.sh中的新增配置 -Dspring.profiles.active=sit-vc
export JAVA_HOME=/opt/jdk1.7.0_79
export JAVA_BIN=/opt/jdk1.7.0_79/bin
export PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/bin
export CLASSPATH=.:/lib/dt.jar:/lib/tools.jar
export JAVA_OPTS="-Djava.library.path=/usr/local/lib -server -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.d
efaultReadTimeout=60000 -Djmagick.systemclassloader=no -Dnetworkaddress.cache.ttl=300 -Dsun.net.inetaddr.ttl=300 -Dspring.profiles.active=sit-vc"
export JAVA_HOME JAVA_BIN PATH CLASSPATH JAVA_OPTS
$CATALINA_HOME/bin/startup.sh -config $CATALINA_BASE/conf/server.xml
-
- web项目设置在Servlet的context parameter
//Servlet2.5-1
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</init-param>
</servlet>
//servlet3.0-2
public class WebInit implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext container) throws ServletException {
container.setInitParameter("spring.profiles.default","dev");
}
}
//web.xml
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
2.5事件(Application Event)
spring的Application Event为Bean与Bean之间的消息通信提供了支持.当一个Bean处理完一个任务后,希望另一个Bean知道并能做相应的处理.Bean 1监控Bean2
需要遵循入流程
- 自定义事件,继承ApplicationEvent
- 定义时间监听器,实现ApplicationListener
- 使用容器发布事件.
///highlight_spring4/src/main/java/ch2/event/DemoEvent.java //自定义事件
///highlight_spring4/src/main/java/ch2/event/DemoListener.java //事件监听器
///highlight_spring4/src/main/java/ch2/event/DemoPublisher.java //时间发布器
///highlight_spring4/src/main/java/ch2/event/EventConfig.java //配置类
///highlight_spring4/src/main/java/ch2/event/Main.java //运行
参考文章
3.Spring 高级话题
3.1 Spring Aware
Aware(adj. 意识到的;知道的;有…方面知识的;懂世故的)
容器管理的Bean一般不需要了解容器的状态和直接使用容器,但是在某些情况下,是需要在Bean中直接对IOC容器进行操作的,这时候,就需要在Bean中设定对容器的感知。spring IOC容器也提供了该功能,它是通过特定的Aware接口来完成。
Spring Aware的目的是为了让Bean获得Spring容器的服务.因为ApplicationContext接口继承了MessageSource, ApplicationEventPublisher, ResourceLoader,所以Bean继承了ApplicatioContextAware可以获得Spring容器的所有的服务.当然原则是用什么实现什么.
Aware接口有以下这些:
名称 | 说明 |
---|---|
BeanNameAware | 获取IOC容器中Bean的实例的名称 |
BeanFactoryAware | 获取当前的Bean Factory,这样可以调用容器的服务 |
ApplicationContextAware | 当前的Application context,这样可以调用容器的application服务 |
MessageSourceAware | 获得message source,这样可以获得文本信息 |
ApplicationEventPublisherAware | 应用事件发布器,可以发布事件,spring的Application Event的publisher也可以实现这个来发布事件 |
ResourceLoaderAware | 获得资源加载器ResourceLoader,可以获得外部Resource资源文件. |
在设置Bean的属性之后,调用初始化回调方法之前,Spring会调用aware接口中的setter方法
@Service
public class AwareService implements BeanNameAware,ResourceLoaderAware{//1
private String beanName;
private ResourceLoader loader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {//2
this.loader = resourceLoader;
}
@Override
public void setBeanName(String name) {//3
this.beanName = name;
}
//bob,外部能渠道Bean名称(awareService)
public String getBeanName(){
return beanName;
}
public void outputResult(){
System.out.println("Bean的名称为:" + beanName);
Resource resource =
loader.getResource("classpath:com/wisely/highlight_spring4/ch3/aware/test.txt");
try{
System.out.println("ResourceLoader加载的文件内容为: " + IOUtils.toString(resource.getInputStream()));
}catch(IOException e){
e.printStackTrace();
}
}
}
///highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/aware/AwareService.java
//highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/aware/AwareConfig.java
///highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/aware/Main.java
///highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/aware/test.txt
3.2 多线程
TaskExecutor :任务执行器,来实现多线程和并发编程。
ThreadPoolTaskExecutor:实现一个基于线程池的TaskExecutor。
@EnableAsync:配置类中通过@EnableAsync开启对异步任务(非阻碍)的支持。
@Async:来声明其是一个异步任务。
TaskExecutor //源码
org.springframework.core.task public interface TaskExecutor extends Executor
ThreadPoolTaskExecutor //源码
org.springframework.scheduling.concurrent public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
//包含一个线程池并且循环调用2个异步任务的例子.
/highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/taskexecutor/TaskExecutorConfig.java
/highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/taskexecutor/AsyncTaskService.java
///highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/taskexecutor/Main.java
3.3 计划任务
@EnableScheduling 配置类中开启计划任务支持.
@Scheduled 在类的方法中声明这是一个计划任务.
@Scheduled支持
@Scheduled(cron="00 14 17 ? * * ") //每日17:14分运行
@Scheduled(cron="${CountDayTask}") //也可以配置在config.properties中 CountDayTask=00 14 17 ? * *
@Scheduled(fixedRate = 5000) //每隔五秒执行一次
3.4 条件注解@Conditional
@Conditiona1: 根据满足某一个特定条件创建一个特定的 Bean。
比方说, 当某一个 jar包在一个类路径下的时候, 自动配置一个或多个 Bean,或者只有某个 Bean被创建才会创建另外一个Bean。总的来说,就是根据特定条件来控制 Bean的创建行为,这样我们可以利用这个特性进行一些自动的配置。
存在一个
//源码中的接口Condition
package org.springframework.context.annotation;
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
//如果要使用Conditional,则需要实现接口Condition,并implement方法matches.
public class LinuxCondition implements Condition {
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}
源码接受:一个接口ListService,针对Linux和windows个各有一个实现:LinuxListService,WindowsListService;</br> 两个LinuxCondition和WindowsCondition都实现了Condition并重写matches;然后由ConditionConifg配置来指明说明情况用哪个Service;Main使用Bean的时候就会得到相应(根据condition)的Bean了.
完整源码
/highlight_spring4/src/main/java/com/wisely/highlight_spring4/ch3/conditional/ListService.java, LinuxListService.java,WindowsListService.java,LinuxCondition.java,WindowsCondition.java,ConditionConifg.java,Main.java.
3.5 组合注解和元注解
元注解:注解到别的注解上的注解.
组合注解:被注解的注解为组合注解,组合注解具备元注解的功能.
3.6 @Enable*注解的工作原理
@EnableAspectJAutoProxy 开启对 AspectJ自动代理的支持。
@EnableAsync 开启异步方法的支持 。
***@EnableSchedulmg***开启计划任务的支持 。
***@EnableWebMvc***开启 Web MVC的配置支持。
***@EnableConfiguratlonProperties***开启对@ConfigurationProperties注解配置 Bean的支持。
***@EnableJpaRepositories***开启对 Spring Data JPA Repos1tory 的支持。
***@EnableTransactionManagement***开启注解式事务的支持 。
***@EnableCachmg***开启注解式的缓存支持 。
工作原理分三种情况: p63-65
- 1 ) 直接导入配置类
- 2 ) 依据条件选择配置类
- 3 ) 动态注册Bean
3.7 测试
Spring TestContext Framework对集成测试进行顶级支持.不依赖于特定框架,支持Junit,也支持TestNG.
pom.xml:
org.springframework:spring-test:4.1.5.RELEASE
junit:junit:4.11
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import junit.framework.Assert;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfig.class})
@ActiveProfiles("prod")
public class DemoBeanIntegrationTests {
private TestBean testBean;
public void prodBeanShouldInject(){
String expected = "from production profile";
String actual = testBean.getContent();
Assert.assertEquals(expected, actual);
}
}
/highlight_spring4/src/main/java/ch3/fortest/TestConfig.java,TestBean.java
4.Spring mvc基础
5.Spring Boot基础
6.Spring Boot核心
7.Spring Boot的Web开发
8.Spring Boot的数据访问
9.Spring Boot的企业级开发
10.Spring Boot开发部署与测试
11.Spring 应用监控
Spring Boot有四大神器,分别是auto-configuration、starters、cli、actuator