IOC
IOC 控制反转,把管理对象的能力还给程序员。而不是由程序控制对象的。
举个例子
原本是在main函数中 new一个对象
在Spring中,是声明一个对象,然后通过IOC容器把,这个对象赋值,我们通过配置文件控制IOC容器,这样就相当于控制的权利在我们的手上了
AOP
面向切面编程。我的理解就是功能增强,相当于包装,在不改动原有功能的情况下,给他套上新的功能。一般来说把很多模块都要用的但是跟自身不想管的功能封装起来,减少代码量,降低耦合度。
常见的Cglib和JDK动态代理。比如说可以给所有的service增加一个日志功能类似。
Bean
bean表示的是被IOC管理的对象
通过配置文件来管理
<bean id="..." class="....">
<properties
or
<constructor
</bean>
bean的作用于
- singleton 单例模式,这个程序中,只有这个对象
- prototype:每次请求都会创建一个新的实力
- request:每一次http请求都会创建一个新的实力
- session:一个新的session创建一个新的实例
在xml中的scope文件中配置
@Configuration和@Bean
@Configuration
我差不多理解这个注解的使用方法
这是一个修饰类的注解。修饰这个类,然后类中的方法使用@Bean。
@Configuration
public class TestConfiguration {
public TestConfiguration() {
System.out.println("TestConfiguration容器启动初始化。。。");
}
}
等价于
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
@Bean这个注解一般使用在被@Configuration修饰的类中
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
等价于
<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
将一个类声明为bean类的注解
@Component 本质上这四个注解都是相同的,就是区分哪一层
@Repository 在dao层使用
@Service 在service层使用
@Controller 在controller层使用,就是其实你也没有想到吧,你定义的@Controller其实是一个@Componet其实是一个@Configuration
@Bean和@Component的区别
- @Bean是作用在方法上的,而@Component是作用在类上面的
- @Component是通过@ComponentScan定义的路径自动扫描,自动装配进去的,@Bean作用在方法上,通过返回的实例,来注册实例。
SpringMVC
MVC都代表着什么
- Model 可以理解为dao和bean
- View 前端展示页面
- Controller 连接Model 和 View的部分
工作流程
4. 客户端发送请求给DispatcherServlet
5. DispatcherServlet调用HandlerMapping解析对应的Handler
6. 解析到的Handler交给HandlerAdapter处理业务
7. 处理业务完毕之后返回一个ModelAndView对象。Model是数据对象,View是逻辑上的View
8. 根据虚拟的View找到真实页面,根据Model中的值渲染页面然后交还给请求者。
Spring中用到的设计模式
- 单例模式
- 工厂模式
- 包装器模式
- 代理模式
- 适配器模式
Spring重要注解
1. @SpringBootApplication
介绍这个注解顺便好好了解一下什么是自动装配。
官方介绍这个注解
@SpringBootApplication == @Configuration+@EnableAutoConfiguration+@ComponentScan这三个注解的集合。
@EnableAutoConfiguration:启动Springboot自动配置机制
@Configuration:允许以类作为xml文件的方式,配置bean
@ComponentScan:告诉Springboot项目中又那些路径下有bean需要被自动配置。
-
@Autowired自动注入 byType byName。默认是ByType,找不到合适类型的就按名自动注入。且@Autowired和@Resource是刚好相反的。
-
@RestController这个是@ResponseBody和@Controller的集合
- @ResponseBody:使用这个注解之后,就不走视图解析器了。是直接把对象转换成固定格式之后打印在界面上。
-
@Scope声明作用域
-
@POST/GET/PUTMapping == @RequestMapping(value=“xxx”,method=post/get/put)
-
参数传值 @PathVariable用于获得路径参数
-
参数传值 @RequstParam用于获得查询参数
-
@RequestBody读取Request请求的正文部分
-
@Value 读取简单的配置信息
-
@ConfigurationProperties读取配置文件信息的
-
@CrossOrigin解决跨域问题的
-
处理异常的两个标签@ControllerAdvice和@ExceptionHandler
SpringBoot的自动装配
@Retention表明这个注解运行的时间
@Documented
@Target声明了范围
@Inherit表明子类能否继承父类的注解
beanFactory和ApplicationContext的差距
beanFacotry并不会直接生成所有的bean,只有在getBean的时候才会获得对应对象。ApplicationContext不同,他会直接装入所有的bean。并且Application实现了更强大的功能比如信息国际化、支持了时间机制等。
创建一个bean常用的手段
@Component
@Bean + @Configuration
@Bean作用于方法 @Component作用于类
@Bean自定义程度更强
Bean对象其实有现成不安全的问题的,如果实在需要安全,那就使用ThreadLocal这个关键字吧
SpringAop
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理,如下图所示:
JDK是通过实现目标接口实现,Cglib是通过继承来实现
Aop就是面向切面的思想,很关键的就是日志问题。
Spring事务
只是在项目开发中使用到,考虑的是db
Spring自动装配
自动装配是指Spring在上下文里找到对应的bean。实现方式有xml和通过注解实现
配置就是xml手动配置
或者就是@Autowire默认Bytype @Resouce默认ByName @Qulify搭配@Autowire@Qualifier 注释指定注入 Bean 的名称。在SpringBoot中,在@SpringBootApplication注解中有一个注解就是扫描路径下所有的Bean,并完成自动配置,我们自己也可以通过@ComponentScan
Spring的循环依赖问题
首先说明什么是循环依赖问题,
当A 依赖 B,B依赖C,C依赖A,这种情况Spring在初始化容器的时候就不知道应该先初始化哪个。这个问题可以通过懒加载和调用Setter方法注入来解决
SpringBoot的启动流程
1.初始化SpinrgApplication对象。
2. 执行run方法。
- 执行run方法的时候主要执行这样几个动作
- 启动一个计时器,来记录springboot启动所花费的时间
- 初始化一个监听器,去监听run方法的执行
- 初始化Arugument和环境变量
- 打印Banner和版本
- 初始化上下文
- 监听器表明启动完成,计时器关闭
- 发布启动完成事件
- 调用ApplicationRunner和CommandLineRunner
- 最后发布就绪事件ApplicationReadyEvent,标志着SpringBoot可以处理就收的请求了(running())
Spring事务
Spring事务是Aop的最好实现
3. 事务传播性,总共有7种传播方式:默认是progation_required,外层有事务合并到外层,也有progation_supports外层有事务,先挂起,处理完内层事务再处理外层事务。
4. 事务的隔离级别,分别有默认与数据库相同,读已提交xxxx
Aop:底层的实现原理是动态代理,在java中如果实现了接口,就默认走JDK动态代理,如果没有实现接口节奏cglib动态代理。
ThreadLocal:
Synchronized是线程去内存拿变量,并且竞争资源volatile是线程去内存拿变量,但是不竞争资源,而 ThreadLocal,是想提高并发量,然后线程之间的相互隔离,是拿空间来换时间。
每一个线程都有ThreadLocalMap这么一个对象,在这个对象里整
TreadLocal内存泄漏:因为线程一直持有ThreadLocalMap这个对象,一直往里面塞值而且不手动释放,这个时候就有内存泄漏的风险
bio和nio
bio的原理很简单,就是来一个请求创立一个线程来处理链接,带来的问题就是消耗比较大。
CAS的缺点
众所周知,CAS在ABA的情况下,线程1把A变成B,又把B变成A,线程2把A变成C,其实变量A已经发生改变了,但是CAS检测不到,这就会造成数据丢失