Spring之ignoreDependencyInterface方法

前言

ignoreDependencyInterface方法是笔者在阅读Spring源码过程中遇到的,刚看到时还不明白其真正含义,导致笔者对此方法有所误解,冥思苦想许久,依然想不明白,决定做一下实验,做完实验后,恍然大悟!!!

ignoreDependencyInterface方法有什么用?

其作用就是在Spring自动装配Bean的时候忽略掉接口实现类或普通类中的set注入,这么说可能有点抽象,我们来看下面的案例

案例

说明

例如,A接口中有一个B实现类,我不希望它能够使用set进行注入Cat对象,而是使用别的注入方式,那么我们就可以使用到ConfigurableListableBeanFactory接口的ignoreDependencyInterface方法,来看下示例吧

Cat类

package com.spring.demo.test;

public class Cat {
    
}

接口

package com.spring.demo.test;

public interface A {
	void setCat(Cat cat);
}

实现类

package com.spring.demo.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

public class B implements A {
	private Cat cat;

	@Override
	public void setCat(Cat cat) {
		this.cat = cat;
	}

	public Cat getCat() {
		return cat;
	}
}

BeanFactoryPostProcessor实现类

怎么拿到ConfigurableListableBeanFactory接口?我们通过实现BeanFactoryPostProcessor接口可以拿到ConfigurableListableBeanFactory接口并配置自动装配时忽略该接口实现类的set注入

//BeanFactoryPostProcessorImpl.java
package com.spring.demo.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

public class BeanFactoryPostProcessorImpl implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //这里有个注意的点,就是参数传“接口.class or 类.class”都会生效,对于接口实现类和普通类都会生效,因为它在检查的时候只会看当前类或实现的接口里有没有定义set方法(即set注入)
		beanFactory.ignoreDependencyInterface(A.class);
	}
}

spring-context.xml


<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context
	   https://www.springframework.org/schema/context/spring-context.xsd">

	<bean id="cat" class="com.spring.demo.test.Cat" >bean>
	<bean id="b" class="com.spring.demo.test.B" autowire="byType"/>  //一定要开启自动装配,byType或byName
	<bean class="com.spring.demo.test.BeanFactoryPostProcessorImpl"/>
beans>

测试

Main.java
package com.spring.demo;

import com.spring.demo.test.A;
import com.spring.demo.test.B;
import com.spring.demo.test.Cat;
import com.spring.demo.test.Dog;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
		System.out.println(bean);
	}
}

两种情况

  1. 不调用ignoreDependencyInterface方法
    在这里插入图片描述
    通过debug可以发现,cat对象是成功被注入了的,接下来我们再看看调用ignoreDependencyInterface方法会是什么结果

  2. 调用ignoreDependencyInterface方法
    Spring之ignoreDependencyInterface方法_第1张图片

​ 调用ignoreDependencyInterface方法后set注入失败,值为null

以上是针对接口实现类的,那我们还有一种情况,直接忽略普通类可不可以呢?

首先,把B类实现的A接口去掉,然后再把beanFactory.ignoreDependencyInterface(A.class);改成beanFactory.ignoreDependencyInterface(B.class);,我们直接忽略普通类看看能不能注入成功

可以看到结果是注入失败的
在这里插入图片描述

总结

做完实验后,我们得出以下总结:

  1. ignoreDependencyInterface方法是用来忽略接口实现类和普通类set注入的
  2. 不论是接口实现类还是普通类,都能进行配置忽略set注入(可以通过其他注入方式进行依赖注入)

你可能感兴趣的:(spring)