你们不了解的spring注入方式及mybatis对其的使用

  • 前言

    在看博主这篇文章之前,请大家思考一个问题:spring@Autowired和@Resource这两个注解是干嘛用的?很多人会回答,@Autowired是通过byType注入属性的,@Resource默认使用byName注入,也可以使用byType方式注入,在你们眼里可能觉得这两个注解就是Spring开启不同注入方式的方法,不使用这两个注解或者不在xml中配置的话就不能注入,但其实spring的byType与@Autowired是完全两码事,原因如何我们往下看。

 

  • 正文

    我们来看下面这段代码:

@Component
public class UserClass {

    private OrderClass orderClass;

    public OrderClass getOrderClass() {
        return orderClass;
    }

    public void setOrderClass(OrderClass orderClass) {
        this.orderClass = orderClass;
    }
}

 

public class TestAUtowired {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext
                = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(annotationConfigApplicationContext.getBean(UserClass.class).getOrderClass()+"-----");
    }
}

我们在一个UserClass中引入另一个OrderClass,并提供setter、getter方法,然后打印出getOrderClass的值,很显然是空的:

接下来,我们实现自己的一个Registar:

public class MyRegistar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 
    BeanDefinitionRegistry registry) {
        GenericBeanDefinition genericBeanDefinition = 
                        (GenericBeanDefinition)registry.getBeanDefinition("userClass");
        genericBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        registry.registerBeanDefinition("userClass",genericBeanDefinition);
    }
}

并且通过javaConfig的方式import进去: 

 可以看到,这个对象有值了:

在这过程中,我既没使用@Autowired也没使用@Resource,也没有使用xml进行配置,但是为什么我能注入OrderClass这个对象呢?这个其实就是你们对spring了解的局限性,我们来看org.springframework.beans.factory.support.AbstractBeanDefinition这个类中有四个属性:

    它包含了spring的四中注入方式,在默认的情况下,spring使用的是第一种AUTOWIRE_NO,也就是不自动装配,当你使用了@Autowired或者@Resource时候就会使用自动装配,而如何装配则是通过定义的属性,来完成注入,但是使用@Autowired注入时必须依赖你引入的对象,而spring使用的byType注入时只需要提供setter方法的。上面的MyRegistar就是这个作用,将默认的装配方式改为了byType,只要提供setter方法就可以将属性注入,也就是说,当你想使用byType的时候,可以不加任何注解,也不需要引入任何变量,只需要把默认的装配方式改为AUTOWIRE_BY_TYPE就可以了,然后提供setter方法即可。

    关于这里的应用,可能大家开发过程中没有使用,但是其实MyBatis中队其做了完美的运用,我们来看org.mybatis.spring.annotation.MapperScannerRegistrar这个类,这里面在调用了org.mybatis.spring.mapper.ClassPathMapperScanner的processBeanDefinitions()方法,在这个方法的最后一段,将自动装配方式改成了AUTOWIRE_BY_TYPE

 

 并且在

 org.mybatis.spring.support.SqlSessionDaoSupport中提供了setter方法给SqlSession赋予了新的实现sqlSessionTemplate,

对这些不了解的童鞋可以看博主这篇文章 https://mp.csdn.net/postedit/85619155

  • 总结

  1.  spring默认使用的装配规则是不自动装配----AUTOWIRE_NO
  2. 当你加了@Autowired或者@Resource时候就会使用自动装配
  3. 如果想使用byType方式装配的话,可以不加任何注解或者配置,也不需要引入对象,只需实现org.springframework.context.annotation.ImportBeanDefinitionRegistrar,将默认装配方式改了,然后提供setter和getter方法就行了,byName同理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值