Spring-IOC综述

文章迁移自语雀。

怎么查看spring的文档

ioc综述

说到spring的ioc,其实就是控制反转,为啥需要控制反转呢,其实是为了功能的增强,如果不用spring, 我们直接使用工厂方法,静态工厂方法, 都是是可以获取到对象的,但是如果需求变了,我们在类的生成时,添加了很多信息,使用工厂就不方便了,还有事务等需要统一的处理.一个典型的应用就是mybatis的接口,平时我们都是只需要写mybatis的接口,但是不写他的实现类,由spring生成一个代理的实现类,来进行方法的调用.对于事务的调用,在service上添加了事务,需要调用dao进行统一的控制.所以需要一个统一的bean对象的管理,就是ioc了,当然了,还可以使用google的juice.

说一点spring3和spring4的区别,spring3提供接口注入.

ioc注入

现在看spring ioc的文档, 5.2版本的文档,现在提供的注入方式有两种,构造方法和set方法注入.

如果使用xml进行配置,在写<bean>标签时,默认是使用的类型注入,就是default-autowired=byType

注解注入

说下我们经常使用的@Autowired注解

默认使用的是根据类型注入,如果类型没有找到,就根据属性名在去查找,找不到就报错了.

通过查看spring的源码,当把@Autowired写在属性上的时候,spring是使用的反射,获取该属性的Field,再进行值的设置,完成属性的注入.

@Resource注解可以指定bean的名字和类型,根据属性名注入,跟set方法的名字就没有关系了

自定义bean名字生成

最后说一个自定义bean的名字生成策略

BeanNameGenerator 接口

步骤如下:

1.自定义类实现BeanNameGenerator接口,重写方法

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.BeanNameGenerator;

/**

* 自定义bean name的生成策略

*/

public class MyBeanNameGenerator implements BeanNameGenerator {

   @Override

   public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {

       String className = definition.getBeanClassName();

       System.out.println(className);

       int indexOf = className.lastIndexOf(".");

       if (indexOf != -1) {

           //前面加一个 my,其他的不做处理

           return "my"+className.substring(indexOf + 1, className.length());

       }

       return null;

   }

}

2.通过修改@ComponentScan 指定类名生成策略.

@ComponentScan(value = "com.onyx",nameGenerator = MyBeanNameGenerator.class)

再次运行spring就可以看到生成的bean 名字了.

测试代码如下, 就是个main方法:

public static void main(String[] args) {

AnnotationConfigApplicationContext context =

  new AnnotationConfigApplicationContext(AppConfig.class);

String[] names = context.getBeanDefinitionNames();

for (String name : names) {

 System.out.println(name);

}

}

获取application

如果想要获取到application对象,需要在类上实现接口implements ApplicationContextAware,

在类中定义变量ApplicationContext applicationContext进行接收, 赋值.就可以使用了.

Lookup注解

说一个很特殊的应用场景,在一个类的每个方法中,需要使用的类,每次使用的类都要求是不同的对象,每用一次相当于new 一次, 这个时候需要使用到@LookUp("userDao") 注解,使用的方法上加上,每个方法获取的dao就会一个新的对象,而不是一个单例的dao重用.此注解只能加上方法上.使用方法省略,需要的时候再去具体看吧.

spring bean生命周期回调

InitializingBean初始化接口

DisposableBean销毁对象的接口

注解:

@PostConstruct

@PreDestroy

一个类实现此接口使用使用到具体的回调方法.也可以使用xml的配置,在<bean>标签中使用init-method=init 初始化方法

spring还存在**@DependsOn**注解, 表明此类的生成需要依赖的其他的一个类的步骤.

spring扫描

@ComponentScan 中可以配置 filter等过滤信息,只扫描需要的类,加快spring的启动速度.里面有一套扫描的形式

还有另外一个方法,添加一个依赖.

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-indexer</artifactId>

<version>5.2.3.RELEASE</version>

<optional>true</optional>

</dependency>

这个依赖会加快spring的启动速度.

Primary注解

前段时间做项目,我们项目经理用的eclipse,他启动项目一定要加上@Primary 注解, 否则启动报错,我做的这个项目,我就纳闷了, 我的一个接口就一个实现类,不可能有重名的,不知道eclipse有什么bug,我用idea启动完全没问题.

一个接口,两个实现类,其他地方根据接口注入了,如果不做修改会报错,说找到了两个类.

解决办法 在一个类上标记@Primary 或者使用@Qualifier ,名字做区分.

@Profile

各种环境中类的实例化,类上添加,

激活@Profile.

context.getEnvironment().setActiveProfile("....")

好处就是可以自由的切换类, 配置文件.

spring-jdbc 通用链接,自己做测试用.

spring的循环依赖

修改了application, 之后需要重新reshesh一下.

什么时候用xml

什么时候用注解

什么时候用java config

根据项目来,如果想精通spring,就三者混合这来.

不得不说写总结性的文章真的好要时间,写这个文章的时候,程程刚在睡觉,那时候刚过10点,现在都11点了,只希望疫情能够早点结束,早日能够看到她,我的心情就像外面的濛濛细雨一样,外面的天空是灰蒙蒙的,哎.

2020年2月14日11:08:02

相关推荐
公贵买其鹿3 分钟前
List深拷贝后,数据还是被串改
java
向前看-3 小时前
验证码机制
前端·后端
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹4 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫5 小时前
泛型(2)
java
超爱吃士力架5 小时前
邀请逻辑
java·linux·后端
南宫生5 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石5 小时前
12/21java基础
java
李小白665 小时前
Spring MVC(上)
java·spring·mvc