SpringBoot2

SpringBoot2

微服务的概念

微服务就是将一个大的系统拆分红多个子系统,而后经过REST风格的请求将他们集成起来,进一步简化了分布式系统的开发css

SpringBoot2的特色

  • 约定大于配置,经过引入xx-starter加上自定义的配置文件就能够集成某个组件的java客户端
  • 内置tomcat/undertow
  • 提供快速的测试环境

为何要学这个

天天都在用SpringBoot缺不知道其中的原理,典型的日用而不知。一旦出现开发的问题,就是一顿博客乱找,好久也解决不了问题 因此,理解原理很重要java

Bean的声明周期

1.Spring经过配置,如@SpringBootApplication或@ComponentScan定义的路径(默认为当前包和子包)找到带有@Component的类web

2.解析类定义,把Bean定义发布到Ioc容器中,注意:是定义,不是实例spring

3.Ioc容器装载Bean的定义数据库

4.建立Bean的实例对象api

5.开始扫描@Autowired注入各种资源tomcat

踩坑

@Service
public class Service{
    @Autowired
    public String kafkaHost;
    
    public KafkaAppender;
    public Service(){
        KafkaAppender = new KafkaAppender(kafkaHost);
    }
}
复制代码

注意,当Service被初始化时,会调用构造器,此时kafkaHost还没被Autowired注入,因此这个时候kafkaHost为nullbash

Spring注解说明

Spring注解之Bean注解:

@Configuration
public class AppConfig {
    @Bean(name="user"} 
    public User initUser () {
        User user= new User (); 
        user.setId(100) ;
        user.setUserName();
        return user;
    }
}

@Service    
public class System{
    @Autowired
    private User user;
}   
复制代码

@Bean表示将initUser返回的user装配到Ioc中,并且该bean的name为user。若是没有定义name,则bean的name为方法名(initUser)session

@ComponentScan与@Component

@Component("user")
public class User {
    private id; 
    private String userName; 
    private String note;
}

@Service    
public class System{
    @Autowired
    private User user;
}    
复制代码

注意事项

  • @Component注解做用域默认为singleton
  • @Component表名这个类将被Ioc装配,并且该bean的name为user,若是没有显示定义name,则以类名第一个字母小写做为bean的name
  • @Component使用在不肯定哪个层的时候使用,能够做用在任何层次,把普通pojo实例化到spring容器
  • 不推荐使用@Component注解,而应该使用它的扩展,如@Service、@Repository

业务组件的注释

  • @Component 没有明确角色的组件
  • @Service 在业务逻辑层(Service层)使用
  • @Repository 在数据访问层(dao层)使用
  • @Controller 用于标注控制层组件
  • @RestController 纯REST风格的控制器
@Service
@Service注解做用在类上
@Service注解做用域默认为singleton
使用注解配置和类路径扫描时,被@Service注解标注的类会被Spring扫描并注册为Bean
@Service注解用于标注业务的逻辑组件,即服务组件组件
复制代码
@Repository
@Repository注解做用在类上
@Repository注解做用域默认为singleton
使用注解配置和类路径扫描时,被@Repository注解标注的类会被Spring扫描并注册为Bean
@Repository注解用于标注数据访问组件,即DAO组件
@Repository注解的做用不仅是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型
复制代码

@Controller

@Controller注解做用在类上
使用注解配置和类路径扫描时,被@Controller注解标注的类会被Spring扫描并注册为Bean
@Controller用于标注Web中控制层组件
被@Controller标注的类负责处理由DispatcherServlet分发的请求,
它把用户请求的数据通过业务处理层处理以后封装成一个Model ,而后再把该Model返回给对应的View进行展现
@Controller和@RequestMapping、@RequestParam等一些注解共同处理URL的映射
复制代码

@ComponentScan意味着扫描当前注释类所在的包和子包app

@SpringBootApplication

@SpringBootApplication默认包含了@ComponentScan

@Autowired、@Primary、@Qualifier

Spring最经常使用的注解,根据类型找到对应的Bean进行注入,也就是getBeanByType()

  • 首先根据类型找到对应类型的Bean,若是不惟一,则按照Bean名称进行匹配,若是还找不到,就抛异常
  • 当对应类型的Bean有多个时,@Primary告诉Ioc容器,优先使用带有@Primary标识的Bean
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
public class Woman implements {
}

public class System{
    @Autowired
    private User user;
    这里装配的是Woman
}
复制代码
  • @Qualifier告诉Ioc容器按照类型和名称去找到对应的Bean
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
@Primary
public class Woman implements {
}

public class System{
    @Autowired
    @Qualiefier("man")
    private User user;
    这里装配的是Man
    
    public void heiheihei(@Autowired @Qualiefier("man") User user){};
}
复制代码

@Value与@ConfigurationProperties

从配置文件中获取属性

@Component
@ConfigurationProperties(prefix = "microservice.quickstart")
public class User{
    @Value('${user.name}')
    private String userName;
    //读取配置文件中的microservice.quickstart.user.name配置
}

复制代码

多环境配置下的启动

按照工程创建

  • application.properties
  • application-dev.properties
  • application-test.properties
  • application-prd.properties 启动时添加命令做为参数 java -jar xx.jar -Dpsirng.profiles.active=dev java -jar xx.jar -Dpsirng.profiles.active=test java -jar xx.jar -Dpsirng.profiles.active=prd

@Scope做用在类上和方法上

@Scope用来配置Bean的做用域,有如下几种

singleton单例模式

Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活

prototype原型模式

每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责

request模式

request只适用于Web程序,每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束

session模式

session只适用于Web程序,session做用域表示该针对每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP session内有效

application模式

application只适用于Web程序,全局做用域

@Conditional(TestCondition.class)

这句代码能够标注在类上面,表示该类下面的全部@Bean都会启用配置,也能够标注在方法上面,只是对该方法启用配置。

@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean) @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean) @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean) @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean) @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean) @ConditionalOnNotWebApplication(不是web应用)

spring源码阅读

@EnableWebMvc、WebMvcConfigurationSupport和WebMvcConfigurationAdapter三者之间的区别是什么 @EnableWebMvc注解的类等于extends WebMvcConfigurationSupport 可是没有重写任何方法 SpringBoot WebMVC的自动配置信息都在WebMvcAutoConfiguration这个类中,咱们看他的源码

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638) //Bean的初始化顺序
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
复制代码

其中@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})的意思是,当工程中没有WebMvcConfigurationSupport 时,才会使用WebMvc的自动配置;咱们通常会继承WebMvcConfigurationSupport来自定义配置类, 可是一旦继承WebMvcConfigurationSupport后就会出现新的问题: 会发现Spring Boot的WebMvc自动配置失效,具体表现好比访问不到静态资源(js,css等)了。

拦截器原理

动态代理

上海体育公园有不少大爷大妈相亲,你要去寻找女友。这时,你就问大妈:女儿喜欢什么呀,大妈可能会替她回答。 固然,大妈以为你发际线过高,他也能够直接拒绝。这时,这个大妈就是她女儿的代理

JDK中的使用方式

JDK提供了类Proxy的静态方法:newProxyInstance.

public static Object newProxyInstance(ClassLoader var0, Class<?>[] var1, InvocationHandler var2) throws IllegalArgumentException

这里的invocationHandler是一个接口InvocationHandler对象,定义了invoke方法,这个方法就是实现代理对象逻辑的 经过target\method\args就可以用反射方法运行了

具体见:ProxyBean.java[请学会用IDEA找到对应名字的类]

AOP约定流程

按照咱们上面实现的代码,能够看到,AOP是一种规范化的约定,咱们按照这种约定来使用,就能够实现动态代理 aop-principle.png

拦截器使用AOP的约定

spring-intercetor.png

Spring中使用@AspectJ

Spring AOP使用@AspectJ对方法进行拦截,因此,咱们要先肯定什么地方须要AOP,也就是链接点 有了链接点后,咱们须要一个切面,用来描述流程的织入 请看案例:

MyAspect.java

Myabits中的数据库事务

@Transactional能够放在方法上,也能够放在类上 若是放在类上,则该类的全部方法都默认带了@Transactional 案例请查看

com.liuyiling.microservice.api.controller.DataBaseController.transactional

注意事项

  • @Transactional必须加在public方法上,不然CGlib代理会找不到
  • 正确的设置@Transactional 的 isolation 属性

事务的隔离度,默认值采用 DEFAULT

  • 事务必须注解在非自调用方法上,下面面这个例子事务将不会被调用
@Service
public class OrderService {
    private void insert() {
        insertOrder();
    }
    
    @Transactional
    public void insertOrder() {
    }
}
复制代码
  • 能够指定事务的回滚条件

默认状况下,若是在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring 将回滚事务;除此以外,Spring 不会回滚事务。 若是在事务中抛出其余类型的异常,并指望 Spring 可以回滚事务,能够指定 rollbackFor。例: @Transactional(propagation= Propagation.REQUIRED,rollbackFor= MyException.class)

相关文章
相关标签/搜索