之前写了Springboot的一些入门,至于怎么搭建SpringBoot项目,网上一大堆,就不再阐述了。
ICO:控制反转,依赖注入,对于IOC的概念,大家已经滚瓜烂熟了,这里不再多加阐述(Spring最成功的就是IOC和AOP这两个核心理念,所以思想值得学习,原理搞清楚会对自己帮助很大)
IOC比较简单,这里简单总结一些重要的知识点
IOC的定义:ioc是一种通过描述来生成或者获取对象的技术
-
IOC的两个基本功能:
- 通过描述管理Bean,包括发布和获取Bean
- 通过描述完成Bean之间的依赖关系
-
IOC容器都需要实现的顶级容器接口:BeanFactory
Package org.springframework.beans.factory; import org.springframework.beans.BeansException; improt org.springframework.core.ResolvableType; public interface BeanFactory{ // 前缀 String FACTORY_BEAN_PREFIX="&"; /** 返回指定BeanName(或别名)的Bean 对Protorype:每次返回不同的实例 对Singleton:每次返回相同的实例 */ Object getBean(String name) throws BeansException; /** 返回同时匹配指定BeanName(或别名)和类型的Bean 对Protorype:每次返回不同的实例 对Singleton:每次返回相同的实例 */ <T> T getBean(String name, Class<T> requiredType) throws BeansException; /** 返回指定BeanName(或别名)的Bean,并把所提供的参数作为构造函数参数或工厂方法参数初始化Bean 对Protorype:每次返回不同的实例 对Singleton:抛出BeanDefinitionStoreException异常 */ Object getBean(String name, Object... args) throws BeansException; /** 返回指定类型的Bean,如果存在多个bean定义有相同的类型,则抛NoUniqueBeanDefinitionException异常 对Protorype:每次返回不同的实例 对Singleton:每次返回相同的实例 */ <T> T getBean(Class<T> requiredType) throws BeansException; /** 返回指定类型的Bean,并把所提供的参数作为构造函数参数或工厂方法参数初始化Bean 对Protorype:每次返回不同的实例 对Singleton:抛出BeanDefinitionStoreException异常 */ <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; /** 返回一个ObjectProvider<T>该类型允许对Bean处于not available情况和not-unique情况时做处理 */ <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); /** 作用同上 */ <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); /** 根据指定的BeanName或别名判断factory是否包含bean定义(concrete or abstract, lazy or eager, in scope or not)或由外部注册的单例, 返回true时并不保证一定能通过getBean获取相应实例(eg: 抽象Bean) */ boolean containsBean(String name); /** 根据指定的BeanName或别名判断factory中该Bean的scope是否是Singleton 返回false时不代表scope是prototype(使用自定义的scope时) */ boolean isSingleton(String name) throws NoSuchBeanDefinitionException; /** 根据指定的BeanName或别名判断factory中该Bean的scope是否是Prototype 返回false时不代表scope是Singleton(使用自定义的scope时) */ boolean isPrototype(String name) throws NoSuchBeanDefinitionException; /** 根据指定的BeanName或别名判断factory中该Bean的类型是否与提供的类型匹配 */ boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; /** 根据指定的BeanName或别名判断factory中该Bean的类型是否与提供的类型匹配 */ boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; /** 根据指定的BeanName或别名获取factory中该Bean的类型,对于FactoryBean类型,将调用它的 getObjectType() */ @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; /** 根据指定的BeanName或别名返回factory中该Bean的别名, 如果提供的时别名将返回BeanName和其他别名的数组,BeanName 置与第一个元素 */ String[] getAliases(String name); }
- isSingleton==true:单例模式 ,每次返回的都是同一个对象
- isPrototype==true:每次使用getBean获取对象时,IOC容器就会创建一个新的Bean返回给调用者。
-
注解:
@Bean:将bean注入到IOC容器中
@Component:哪个类被扫描进入Spring IOC容器
-
@ComponentScan:表明采用何种策略去扫描装配Bean,默认只会扫描当前包和其子包,但是也允许我们自定义扫描包
-
配置项
basePackages:定义扫描的包名
basePackageClasses:定义扫描的类
includeFilters:定义满足过滤器条件的Bean才去扫描
-
excludeFilters:排除过滤器条件的Bean
注意:他们都需要通过一个注解@Filter去定义,他有一个type类型,这里可以定义为注解或者正则表达式等类型。classes定义注解类,pattern定义正则表达式。
eg:不想扫描包下面的service类
@ComponentScan(basePackages="com.springboot.*", excludeFilters={@Filter(classes={service.class})})
- 所有标注了@Service的类将不被IOC容器扫描注入
-
main方法在idea中的快捷键:psvm
-
springBoot的启动:
SpringApplication.run(主程序类.class,main函数的参数);
Spring Boot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目里面引入这些starter,相关场景的所有依赖都会导入进来
-
自定义第三方Bean:现实的java应用往往需要引入许多来自第三方的包,并且很有可能希望把第三方包的类对象也放入到Ioc容器中,这是@Bean注解就可以发挥作用了。
eg:引入一个DBCP的数据源
@Bean(name="dataSource") public DataSource getDataSource(){ Properties pros=new Properties(); pros.setProPerty("driver","com.mysql.jdbc.Driver"); ..... return dataSource; }
说明:注解将会用“datasource”的名称作为Bean名称保存到IOC容器中
-
依赖注入:@Autowired:会根据属性的类型找到对应的Bean进行注入,如果对应类型给的Bean不是唯一的,那么它会根据其属性名称和Bean的名称进行匹配,如果匹配得上,就会使用该Bean,如果还是无法匹配,就会抛出异常。
注意:@Autowired是一个默认必须找到对应Bean的注解,如果不能确定其标注属性一定会存在,并且允许这个被标注的属性为null,则可以配置@Autowired的属性required为false.eg:
@Autowired(required=false)
-
Bean的生命周期:
- Bean定义
- Bean初始化
- Bean的生存期
- Bean销毁
资源定位 Bean定义 发布Bean定义 实例化 依赖注入 例如@Component定义的扫描包 将Bean定义保存到BeanDefinition中 Ioc容易装载Bean定义 创建Bean示例对象 例如@Autowired注入各类资源 注意:默认情况下Bean定义被发布到IOC容器之后,会继续去完成初
始化,但有些Bean会收到变化因素的影响,这时我们希望是取出Bean时完成初始化和依赖注入,此时可将Component的配置项lazyInit设为true
@ComponentScan(basepackage="",lazyInit=true)
-
Bean作用域:
作用域类型 使用范围 作用域描述 singleton 所有spring 应用 默认值,IOC容器中只存在单例 prototype 所有spring 应用 每当从IOC容器中取出一个Bean,则创建一个新的Bean session Spring Web 应用 Http会话 application Spring Web 应用 Web工程生命周期 request Spring Web 应用 web工程单次请求 globalSession Spring Web 应用 在一个全局的Http Session中,一个Bean对应一个实例 spring.profile.active:配置环境
-
Spring EL表达语言:可以拥有更为强大的运算规则来更好的装配Bean
@Value("${database.driverName}") String driver; @Value("#{T(System).currentTimeMilis()}") private Long initTime=null; @Value("#{beanName.str}") private String otherBeanProp=null; @Value("#{beanName.str?.toUpperCase()}") private String ortherBeanProp=null; @Value("#{beanName.str eq 'springBoot'}")
- ${......}代表占位符:会读取上下文的属性值装配到属性中
-
{......}代表启动Spring表达式:具有运算功能
- T(.......)代表引入类
- beanName是spring Ioc容器Bean名称,str是其属性(获取其他的Spring Bean 属性来给当前的Bean属性赋值)
- ?. :判断这个属性是否为null