微服务就是将一个大的系统拆分红多个子系统,而后经过REST风格的请求将他们集成起来,进一步简化了分布式系统的开发css
天天都在用SpringBoot缺不知道其中的原理,典型的日用而不知。一旦出现开发的问题,就是一顿博客乱找,好久也解决不了问题 因此,理解原理很重要java
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
@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
@Component("user")
public class User {
private id;
private String userName;
private String note;
}
@Service
public class System{
@Autowired
private User user;
}
复制代码
@Service注解做用在类上
@Service注解做用域默认为singleton
使用注解配置和类路径扫描时,被@Service注解标注的类会被Spring扫描并注册为Bean
@Service注解用于标注业务的逻辑组件,即服务组件组件
复制代码
@Repository注解做用在类上
@Repository注解做用域默认为singleton
使用注解配置和类路径扫描时,被@Repository注解标注的类会被Spring扫描并注册为Bean
@Repository注解用于标注数据访问组件,即DAO组件
@Repository注解的做用不仅是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型
复制代码
@Controller注解做用在类上
使用注解配置和类路径扫描时,被@Controller注解标注的类会被Spring扫描并注册为Bean
@Controller用于标注Web中控制层组件
被@Controller标注的类负责处理由DispatcherServlet分发的请求,
它把用户请求的数据通过业务处理层处理以后封装成一个Model ,而后再把该Model返回给对应的View进行展现
@Controller和@RequestMapping、@RequestParam等一些注解共同处理URL的映射
复制代码
@ComponentScan意味着扫描当前注释类所在的包和子包app
@SpringBootApplication默认包含了@ComponentScan
Spring最经常使用的注解,根据类型找到对应的Bean进行注入,也就是getBeanByType()
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
public class Woman implements {
}
public class System{
@Autowired
private User user;
这里装配的是Woman
}
复制代码
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){};
}
复制代码
从配置文件中获取属性
@Component
@ConfigurationProperties(prefix = "microservice.quickstart")
public class User{
@Value('${user.name}')
private String userName;
//读取配置文件中的microservice.quickstart.user.name配置
}
复制代码
按照工程创建
@Scope用来配置Bean的做用域,有如下几种
Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活
每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责
request只适用于Web程序,每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束
session只适用于Web程序,session做用域表示该针对每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP session内有效
application只适用于Web程序,全局做用域
这句代码能够标注在类上面,表示该类下面的全部@Bean都会启用配置,也能够标注在方法上面,只是对该方法启用配置。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean) @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean) @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean) @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean) @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean) @ConditionalOnNotWebApplication(不是web应用)
@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提供了类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-principle.png
spring-intercetor.png
Spring AOP使用@AspectJ对方法进行拦截,因此,咱们要先肯定什么地方须要AOP,也就是链接点 有了链接点后,咱们须要一个切面,用来描述流程的织入 请看案例:
MyAspect.java
@Transactional能够放在方法上,也能够放在类上 若是放在类上,则该类的全部方法都默认带了@Transactional 案例请查看
com.liuyiling.microservice.api.controller.DataBaseController.transactional
事务的隔离度,默认值采用 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)