title: Spring Boot实战学习笔记1
tags:Spring Boot实战
本文为学习Spring Boot实战的学习笔记,学习了一遍,但是好记性不如烂笔头,所以文章记录下来。图书购买地址为: https://item.jd.com/11894632.html.
Spring Boot实战学习笔记1
Spring Boot实战学习笔记2
Spring Boot实战学习笔记3
Spring Boot实战学习笔记4
Spring Boot实战学习笔记5
Spring-Core:核心工具类,Spring其它模块大量使用Spring-Core
Spring-Beans:Spring定义的Bean的支持
Spring-Context:运行时Spring容器
Spring-Context-Support:Spring容器对第三方包的集成支持
Spring-Expression:使用表达式语言在运行是查询和操作对象
Spring-AOP:基于代理的AOP支持
Spring-Aspects:基于AspectJ的支持.
Spring-Messageing:对消息架构和协议的支持
Spring-Web:提供基础的Web集成的功能,在Web项目中提供Spring的容器
Spring-Webmvc:提供基于Servlet的Spring MVC
Spring-WebSocket:提供WebSocket功能
Spring-Webmvc-Portlet:提供portlet环境支持.
Spring-JDBC: 提供以 JDBC访间数据库的支持
Spnng-TX: 提供编程式和声明式的事务支持
Spnng-0RM: 提供对对象/关系映射技术的支持
Spring-0XM:提供对对象/xml映射技术的支持
Spring-JMS: 提供对 JMS的支持。
Spring.io 生态体系请点击查看
四大原则:
控制反转: (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注解.
**AOP:**面向切面编程,相对于OOP面向对象编程.
AOP的目的是解耦,AOP让一组类共享相同的行为。
在OOP中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足.
Spring 支持AspectJ的注解切面编程.
AOP
org.springframework
spring-aop
${spring-framework.version}
//注意,由于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#
Scope描述的是Srping 容器如何新建Bean的实例的.Spring的Scope有:
写法如下:
@Service
@Scope("prototype")
public class DemoPrototypeService{
}
配置文件: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配置中的
//扫描配置路径
@ComponentScan(basePackages = "com.wisely.springboot.javaconfig") //配置扫描包
//读取配置文件
@PropertySource(value= {"classpath:jdbc.properties,classpath:jdbc.properties2"})
在Bean的使用之前或使用之后做些必要的操作,Spring对Bean的生命周期操作也提供了支持.
@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();
}
}
Profile为在不同环境下的使用不同的配置.
@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
//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
//Servlet2.5-1
dispatcher
org.springframework.web.servlet.DispatcherServlet
spring.profiles.active
dev
//servlet3.0-2
public class WebInit implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext container) throws ServletException {
container.setInitParameter("spring.profiles.default","dev");
}
}
//web.xml
spring.profiles.default
dev
可以参考文章
spring的Application Event为Bean与Bean之间的消息通信提供了支持.当一个Bean处理完一个任务后,希望另一个Bean知道并能做相应的处理.Bean 1监控Bean2
需要遵循入流程
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
参考文章
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
@EnableScheduling 配置类中开启计划任务支持.
@Scheduled 在类的方法中声明这是一个计划任务.
@Scheduled支持
@Scheduled(cron="00 14 17 ? * * ") //每日17:14分运行
@Scheduled(cron="${CountDayTask}") //也可以配置在config.properties中 CountDayTask=00 14 17 ? * *
@Scheduled(fixedRate = 5000) //每隔五秒执行一次
fixedRate,fixedDelay,cron区别
@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; 两个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.
元注解:注解到别的注解上的注解.
组合注解:被注解的注解为组合注解,组合注解具备元注解的功能.
@EnableAspectJAutoProxy 开启对 AspectJ自动代理的支持。
@EnableAsync 开启异步方法的支持 。
***@EnableSchedulmg***开启计划任务的支持 。
***@EnableWebMvc***开启 Web MVC的配置支持。
***@EnableConfiguratlonProperties***开启对@ConfigurationProperties注解配置 Bean的支持。
***@EnableJpaRepositories***开启对 Spring Data JPA Repos1tory 的支持。
***@EnableTransactionManagement***开启注解式事务的支持 。
***@EnableCachmg***开启注解式的缓存支持 。
工作原理分三种情况: p63-65
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
Spring Boot有四大神器,分别是auto-configuration、starters、cli、actuator