Spring学习02-[Spring容器核心技术IOC学习]

什么是bean?

被Spring管理的对象就是bean,和普通对象的区别就是里面bean对象里面的属性也被注入了。

如何配置bean?

@Component方式、@bean配合配置类的方式、@import导入方式、类实现importSelect的方式

@Component方式

在需要被注册成bean的类上加上这个注解就可以了,只要spring能够扫描到,配置了@Component的类会被注册成bean

@Component的扩展注解还有@Service、@Repository

@bean配合配置类的方式

在这里插入图片描述
@bean写在方法上面并且结合配置类

@Configuration
@ComponentScan
public class SpringConfig {
    @Bean
    public User user(){
        return new User();
    }
}

特别注意@bean底层会走cglib动态代理进行增强,代理逻辑就是先从spring容器中去找,如果没找到才会创建bean,找到了直接返回,目的是防止多例bean

  • 测试类
 @org.junit.Test
    public void test(){
        //要依赖spring注入,就需要从spring容器中获取UserService
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = (User) context.getBean("user");
        System.out.println(user);
    }

在这里插入图片描述

@import导入方式

@import注解导入的类会被spring注册成一个bean,一般这个注解放在配置类上,但是也可以放在其他ben类上

@Configuration
@ComponentScan
@Import(User.class)
public class SpringConfig {

}
  • 测试
 @org.junit.Test
    public void test(){
        //要依赖spring注入,就需要从spring容器中获取UserService
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = (User) context.getBean(User.class);
        System.out.println(user);
    }

实现ImportSelector类的方式-批量注册bean

一般配合@import注解使用

@Import(实现ImportSelector.class)

  • 实现了ImportSelector的类
    重写selectImports方法,返回一个字符串数组,里面的内容就是要注册成bean的类的路径全限定名

可以批量注册bean(通过实现selectImports,返回bean的完整类路径字符串数组)

public class UserImportSelect implements ImportSelector {

    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.spring.bean.User"};
    }
}
  • 配合@import
@Configuration
@ComponentScan
@Import(UserImportSelect.class)
public class SpringConfig {

}
  • 测试
 @org.junit.Test
    public void test(){
        //要依赖spring注入,就需要从spring容器中获取UserService
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = (User) context.getBean(User.class);
        System.out.println(user);
    }

实现ImportBeanDefinitionRegistrar的方式

调用BeanDefinition注册器,手动注册一个bean

一般也是配合@import注解使用

public class UserImportSelect implements ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        //调用BeanDefinition注册器,手动注册一个bean

        RootBeanDefinition beanDefinition=new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.spring.bean.User");

        registry.registerBeanDefinition("user",beanDefinition);
    }
}
  • 配合@import注解
@Configuration
@ComponentScan
@Import(UserImportSelect.class)
public class SpringConfig {

}
  • 测试
 @org.junit.Test
    public void test(){
        //要依赖spring注入,就需要从spring容器中获取UserService
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = (User) context.getBean(User.class);
        System.out.println(user);
    }

实例化bean

Spring在实例化bean的时候,当扫描某个类发现有@component或者其他注解的时候,会调用这个类的无参构造函数,从而实例化bean

推断构造函数

规则:

  • 默认使用无参构造函数
  • 无参构造函数和有参构造函数同时存在,也会默认调用无参构造函数
  • 如果只有一个有参构造函数,spring会用有参构造函数,同时会将有参构造函数的参数实例化bean
  • 如果有多个有参构造函数,spring就不知道调用哪个了,必须指定默认的构造函数。指定方法就是方法上添加@Autowired注解,如下所示
@Data
public class User {
    private Integer id;
    private String name;

    private Person person;

    private UserService userService;

    public User(Person person) {
        System.out.println("创建user的构造函数");
        this.person = person;
    }

    //指定默认的构造函数
    @Autowired
    public User(Person person, UserService userService) {
        this.person = person;
        this.userService = userService;
    }
}

使用实例工厂方法实例化----@Bean的方式

可以自由的选择构造函数进行实例化

使用工厂Bean。实例化-----FactoryBean

  • FactoryBean是一个接口

  • 需要有一个Bean,一旦这个Bean实现FactoryBean就成为了特殊的Bean
    在这里插入图片描述

  • 可以自由的选择构造函数进行实例化
    特殊 就是根据bean的名字实际上是获取getObject返回的对象(狸猫换太子)

  • 实现FactoryBean的方法

@Data
@Component
public class User implements FactoryBean<Person> {
    private Integer id;
    private String name;

    //特殊 就是根据bean的名字实际上是获取getObject返回的对象(狸猫换太子)
    public Person getObject() throws Exception {
        return new Person();
    }

    public Class<?> getObjectType() {
        return null;
    }
}
  • 测试
 @org.junit.Test
    public void test(){
        //要依赖spring注入,就需要从spring容器中获取UserService
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        System.out.println(context.getBean("user"));
    }

可以看到返回的bean是getobject方法返回实例化bean
在这里插入图片描述

依赖注入(DI)

@Autowired

要实现依赖注入一定要使用@Autowired?
1、@Bean方法的参数会自动注入
2、构造函数的参数也会自动注入

特性

  • 可以写在方法、构造函数、字段
    1、写在构造函数(一般是多个有参构造函数,用@Autowired加在构造函数上来指定默认的构造函数)
    2、写在字段:表示依赖注入
    3、写在方法:方法里的参数会自动注入(Spring会自动调用你的@Autowired方法进行自动注入)

如何注入

先byType后byName:如果有多个类型,就根据名字进行匹配

在这里插入图片描述
在这里插入图片描述

@Resource

会先根据名字找,再根据类型找
在这里插入图片描述
总结:现在有构造器注入(构造函数的参数会自动注入)、set注入(set方法加@Autowired注解也会自动注入)

@value

我们可以通过@value注解对字段值进行注入

直接值

@Data
@ToString
public class User {
    @Value("zzq")
    private String name;
    @Value("25")
    private Integer age;
}
  • 测试
    在这里插入图片描述

对外部文件的引用(SpringBoot配置文件)

这儿不展开说明了,记得加@PropertySource("")注解

@PropertySource("")

在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值