Spring IOC示例

目录

1.spring ioc依赖查找

2.spring ioc依赖注入


1.spring ioc依赖查找

通话xml的方式

新建dependency-lookup-context.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="iocDemoUser" class="com.demo.ioc.spring.ioc.overview.IocDemoUser" primary="true">
        <property name="name" value="jack"/>
        <property name="age" value="22"/>
        <property name="address" value="成都"/>
    </bean>

    <bean id="usaUser" class="com.demo.ioc.spring.ioc.overview.pojo.UsaUser">
        <property name="name" value="usa"/>
        <property name="age" value="220"/>
        <property name="address" value="美国"/>
    </bean>
    
    <bean id="userObjectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
        <property name="targetBeanName" value="iocDemoUser"/>
    </bean>
</beans>

spring依赖查找方式有:按名称直接查找,ObjectFactory懒加载方式查找,按注解查找,以及按类型查找所有Bean

示例:

public class DependencyLookupDemo {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:META-INF/dependency-lookup-context.xml");
        System.out.println("直接查找:");
        lookupInRealtime(ctx);
        System.out.println("lazy查找:");
        lookupLazy(ctx);
        System.out.println("注解查找:");
        lookupByAnnotation(ctx);
        System.out.println("集合查找:");
        lookupCollectionByType(ctx);
    }

    private static void lookupCollectionByType(BeanFactory ctx) {
        if (ctx instanceof ListableBeanFactory) {
            ListableBeanFactory lCtx = (ListableBeanFactory) ctx;
            Map<String, IocDemoUser> beansOfType = lCtx.getBeansOfType(IocDemoUser.class);
            System.out.println(beansOfType);
        }
    }

    //注解查找
    private static void lookupByAnnotation(BeanFactory ctx) {
        if (ctx instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) ctx;
            Map<String, Object> beans = listableBeanFactory.getBeansWithAnnotation(Usa.class);
            System.out.println(beans);
        }
    }

    //ObjectFactory方式懒加载查找
    private static void lookupLazy(ClassPathXmlApplicationContext ctx) throws Exception {
        ObjectFactory<IocDemoUser> userObjectFactory = (ObjectFactory<IocDemoUser>) ctx.getBean("userObjectFactory");
        System.out.println(BeanUtils.describe(userObjectFactory));
        Object object = userObjectFactory.getObject();
        System.out.println(BeanUtils.describe(object));
    }

    //实时查找
    private static void lookupInRealtime(ClassPathXmlApplicationContext ctx) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Object user = ctx.getBean("iocDemoUser");
        System.out.println(BeanUtils.describe(user));
    }
}

输出:

直接查找:
{address=成都, name=jack, age=22}
lazy查找:
{object=com.demo.ioc.spring.ioc.overview.IocDemoUser@57e1b0c}
{address=成都, name=jack, age=22}
注解查找:
{usaUser=com.demo.ioc.spring.ioc.overview.pojo.UsaUser@46daef40}
集合查找:
{iocDemoUser=com.demo.ioc.spring.ioc.overview.IocDemoUser@57e1b0c, usaUser=com.demo.ioc.spring.ioc.overview.pojo.UsaUser@46daef40}

bean class

public class IocDemoUser {
    private String name;
    private Integer age;
    private String address;
}

@Usa
public class UsaUser extends IocDemoUser {
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Usa {
}

2.spring ioc依赖注入

新建dependency-injection-context.xml配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="dependency-lookup-context.xml"/>
    <bean id="userRepository" class="com.demo.ioc.spring.ioc.overview.repository.UserRepository" 
          <!--按类型注入-->
          autowire="byType">
    </bean>
</beans>

示例代码:

public class DependencyInjectionDemo {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:META-INF/dependency-injection-context.xml");
        UserRepository userRepository = (UserRepository) ctx.getBean("userRepository");
        System.out.println(userRepository);

        System.out.println("ObjectFactory<ApplicationContext> : " + userRepository.getAppFactory().getObject());
        System.out.println("userRepository.getBeanFactory() == ctx: " + (userRepository.getBeanFactory() == ctx));

        //报错(说明依赖查找和依赖注入的范围不一样)
//        ctx.getBean(BeanFactory.class);
    }
}

输出:

 

UserRepository{userList=[com.demo.ioc.spring.ioc.overview.IocDemoUser@5bc79255, com.demo.ioc.spring.ioc.overview.pojo.UsaUser@47ef968d], beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@5ebec15: defining beans [iocDemoUser,usaUser,userObjectFactory,userRepository]; root of factory hierarchy, userFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider@4f063c0a, appFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider@1e6d1014}
ObjectFactory<ApplicationContext> : org.springframework.context.support.ClassPathXmlApplicationContext@300ffa5d, started on Sun Jun 13 21:47:46 CST 2021
userRepository.getBeanFactory() == ctx: false
userRepository.getAppFactory().getObject() == ctx: true

UserRepository

public class UserRepository {
    private Collection<IocDemoUser> userList;
    private BeanFactory beanFactory;
    private ObjectFactory<IocDemoUser> userFactory;
    private ObjectFactory<ApplicationContext> appFactory;
    //getter and setter
}

总结:

可见spring ioc的依赖查找和依赖注入的源并不是完全相同的

依赖注入包含了三个源:

  • 自定义bean
  • 容器内建bean
  • 器內建依赖

从AbstractApplicationContext的refresh方法中

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
            ...
   }

看到prepareBeanFactory中内建了很多Bean及依赖

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值