Spring (IOC)笔记

单例和多例

  • 注解中声明单例通过@Scope,配置文件就是在bean的xml中加scope属性
  • spring默认类是单例的,而且在IOC容器启动时就创建了实例
  • 如果使用多例,对象在使用时创建
  • 单例bean可以通过懒加载实现单例bean在使用时创建
  • SpringMVC中的controller默认是单例的,在web中,不能在controller中添加非静态成员变量,如果非要使用,就将controller声明为多例的.这是因为单例的controller在web的并发情况下是不安全的,非静态成员变量会被重复利用而无法满足需求.

给容器中注册组件

  • 包扫描@componentScan+组件标注注解 (@Controller/@Service/@Repository/@Component)[我们自己的bean]
  • @Bean[导入的第三方包里面的组件]
  • @Import[快速给容器中导入一个组件]
    1:@Import(). 参数为类的类型 .class
    2:参数还可以为一个ImportSelector接口的实现类,该实现类返回需要导入的类的全限定名组成的字符串数组.spring-boot底层用的很多
    3:参数还可以是一个ImportBeanDefinitionRegistrar接口的实现类,
  • 使用FactoryBean创建bean
    使用时创建一个实现FactoryBean的实现类,内部实现工厂bean的三个抽象方法,
    工厂bean的作用是包装一个bean,在getObject()方法的实现中实现自己想实现的功能,返回的是被包装的bean.在其他地方获取这个工厂bean,得到的bean类型是被包装的bean,如果想获取工厂bean,在名称前加上"&"即可.

Bean的初始化和销毁(Bean的生命周期)

  • 我们可以自定义初始化和销毁方法
  • (单例)容器启动时调用bean的构造器,bean创建并赋值好后调用初始化方法,容器关闭时,调用bean的销毁方法
  • (多例)获取bean的时候创建bean,bean创建好并赋值好后调用初始化方法,容器关闭不调用销毁方法,容器不会管理多实例bean.
  • 指定初始化和销毁方法 :
    1:在bean类中创建初始化和销毁方法,然后在@Bean()中通过init-method和destroy-method方法指定自己自定义的初始化和销毁方法.
    2:通过让bean实现InitializingBean接口实现初始化 , 通过让bean实现DisposableBean接口实现销毁
    3: 使用JSR250的@PostConstruct,执行初始化 @PreDestroy执行销毁
    4:通过实现BeanPostProcessor接口指定初始化前后的操作
  • spring 底层对BeanPostProcessor的使用
    bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async

属性赋值

  • @Value
    1 : 使用基本数值赋值
    2 : 使用SpEL: #{}
    3: 可以写${} :去除配置文件(.properties)中的值(运行在环境变量中的值)
    4 : 在配置类上加 @PropertiesSource()/@PropertiesSources()加载外部配置文件,保存在运行的环境变量中

自动装配

  • @Autowired
    • 默认优先按照类型去容器中寻找相对应的组件,applicationContext.getBean(.class)
    • 如果找到多个相同类型的组件,再将属性的名称作为id去寻找bean
    • 如果需要指定bean名称,使用@Qualifier(name)
    • 自动装配默认一定要将属性赋值好,否则会报错
    • 通过autowired的required = false选择非必须装配
    • 使用@Primary是标注在bean声明上的,使得spring遇到相同类型bean选择时,首选这个bean
    • 可以在构造器,setter,参数,属性处使用
    • @Autowired标注在setter方法上,spring调用方法创建bean,如果该bean的创建需要另一个bean,将需要的bean作为setter方法的参数,spring在构造时,会从容器中拿到bean注入
    • 构造器上,默认加载容器中的组件,容器启动时会自动调用无参构造器创建对象,将@Autowired加在有参构造器上,spring创建时调用有参构造器,如果bean只有一个有参构造器,有参构造器的@Autowired可以省略
    • @Bean标注的方法创建对象时,方法参数如果是另一个bean,从容器中获取,这个方法参数可以使用或不使用@Autowired
  • @Resource@Inject [Java 规范] 脱离spring也可以用
    • @Resource(name=)默认按照组件名称进行装配,不支持@Promary和required
    • @Inject没有required
  • 自定义组件(bean)想要使用Spring底层的组件(ApplicationContext/BeanFactory),需要实现XXXAware接口:在创建对象的时候,会调用接口规定的方法注入相关组件
    • ApplicationContextAware接口,实现setApplicationContext方法,将applicationContext获取到bean中
  • @Profile
    • 指定组件(bean)在哪种环境中才能被创建,默认是default环境
    • spring为我们提供的根据当前环境,动态的切换和激活一系列的功能
    • 例如,我们需要实现不同开发阶段的数据源的切换,我们首先创建不同数据源的bean,然后在不同bean上标注@Profile(环境名),
    • 切换环境:
      • 在运行参数中添加 -Dspring-profiles.active = 环境名
      • 使用AnnotationConfigApplicationContext无参构造器创建ApplicationContext对象applicationContext,然后使用applicationContext.getEnvironment().setActiveProfiles(环境名)设置环境,再使用applicationcontext.register(主类.class)注册主配置类,最后启动刷新容器applicationContext.refresh()
    • @Profile也可以写在配置类上,只有在指定环境下才加载配置类

IOC

猜你喜欢

转载自blog.csdn.net/qq_36865108/article/details/84781504