spring常用注解
@ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。该注解一般会配合@RequestMapping一起使用。
@Controller:用于定义控制器类,在spring 项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。
@RestController:用于标注控制层组件(如struts中的action),@ResponseBody和@Controller的合集。
@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。
@EnableAutoConfiguration:Spring Boot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。例如,如果你的classpath下存在HSQLDB,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库”。你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。
@ComponentScan:表示将该类自动发现扫描组件。个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。
@Configuration:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。
@Import:用来导入其他配置类。
@ImportResource:用来加载xml配置文件。
@Autowired:自动导入依赖的bean
@Service:一般用于修饰service层的组件
@Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。
@Bean:用@Bean标注方法等价于XML中配置的bean。
@Value:注入Spring boot application.properties配置的属性的值。
@Inject:等价于默认的@Autowired,只是没有required属性;
@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Bean:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
@AutoWired:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。
@Qualifier:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用。
@Resource(name=”name”,type=”type”):没有括号内内容的话,默认byName。与@Autowired干类似的事。
spring ioc原理
1.当容器启动的时,spring读取我们通过xml或者注解配置的bean,将其转换成对应的BeanDefination加载到内存,这个BeanDefination中包含了bean的描述信息。然后把这些注册到BeanDefinationRegistry中,BeanDefinationRegistry是一个Map,key是Bean定义的id,value是对应的BeanDefination。
2.当所有的BeanDefination注册完后,spring给我们提供了一个扩展点,在实例化Bean前,spring提供了BeanFactoryPostProcessor接口,实现这个接口可以操作修改BeanDefination中bean的描述信息,像处理配置中的占位符就是在这一部完成的。我们也可以自定义一个类,实现这个接口,去操作Bean的信息。
4.容器启动后会扫描这个map中的BeanDefination,调用createBeanInstanse()方法使用反射创建bean对象。
5.对于实例化后的bean,spring会使用BeanWrapper中封装的反射相关的API来对bean填充属性,对于基本数据类型,按照我们的配置设置,对于引用类型,spring会把已经创建好的对象放入一个Map中,此时spring会检查依赖的对象是否已经在map里了,如果有直接注入,如果没有spring会暂停该对象的实例化,转而先去实例化依赖的对象,完事后再回头来完成该对象的实例化。
6.在填充完属性后,spring提供了一系列的aware接口,可以实现对容器本身一些属性的访问。
7.然后spring又提供了两个扩展点,BeanPostProcessor这里提供了一个before和after方法,来对bean进行增强,AOP的动态代理就是在after当中实现的。至此我们对象的初始化完成。
spring解决循环依赖
循环依赖:spring容器中如果有两个对象互相引用,会出现A引用B,B引用A,当创建对象时,会出现A找不到B的引用,B找不到A的引用。
spring解决循环依赖的,是把创建对象的过程分为了实例化和初始化两个阶段,实例化后还未填充属性的扔到三级缓存中,填充属性的时候,如果发现有互相依赖的对象,可以先持有半成品的对象的引用,完成对象的创建,从而解决循环依赖问题。
spring AOP原理
在配置Aspect的Bean实例化之后,会调用spring的后置处理器BeanPostProcessor去实现。
首先会解析切面中配置的通知和pointCut,每个通知都会解析成一个advisor,然后排序。
在实际需要被代理的类,在初始化后,会调用spring的后置处理器BeanPostProcessor,会拿到之前缓存好的advisor判断当前Bean是否被切点表达式命中或者,当前Bean是否有切点配置的注解标注,如果匹配成功,就会为当前Bean创建动态代理。创建动态代理的有两种方式一种是jdk动态代理和CGLib两种方式,springBoot默认使用CGLib的代理方式。
spring的事务
spring的事务,它实现上其实还是用AOP的原理,比如说方法上添加了@Transaction注解后,spring会基于这个类生成一个代理对象,代理对象对方法做了增强,如果有事务处理,那么会先把事务的自动提交给关闭,然后执行业务逻辑,方法执行完没有异常,事务直接提交,如果有异常,直接回滚。
springBoot的工作原理
自动装配,就是自动把第三方的组件的bean装载到IOC容器中,不需要我们在写相关的配置。
1.引入各个组件的starter,组件中包含了一个@Configuration配置类,在这个配置类中,有@Bean注解声明了组件需要装配到IOC容器里面的Bean对象。
2.这个配置类是放在第三方jar包中的,然后基于约定优于配置的理念把这个配置类的全路径放在META-INF/spring.factories文件中,这样springBoot就可以通过SpringFactoriesLoader知道第三方jar包中配置类的位置。
3.在启动类的@SpringBootApplication这个复合注解下面,有一个@EnableAutoConfiguration这个注解就是来完成自动装配的,在这个注解下面的@Import注解导入了AutoConfigurationImportSelector这个类,这个类继承了了ImportSelector,里面的selectImports会读取spring.factories中配置类,实现对这些配置类的动态加载,从而完成自动装配。