当前位置: 首页 > article >正文

Spring框架详解(IOC容器-上)

IOC( Inversion of Control,控制反转)和DI(dependency injection)是Spring框架的核心特性,也是Spring框架的基础。

Spring框架作为一个IOC容器,负责加载、创建和管理Spring Bean。

接下来介绍基于Spring传统的配置方式——xml配置文件来配置Spring Bean。

控制反转

IOC-控制反转指的是:我们程序员把创建、管理对象的工作交给了Spring框架,而不是自己通过new关键字调用构造方法创建。

依赖注入

在一个Spring Bean中,可以通过DI特性将另外一个Bean作为成员变量(依赖)添加到当前Bean中。

Spring默认不会处理Bean中的成员变量,需要通过一定的配置,让Spring将对应的Bean对象注入到当前Bean中。

Spring依赖注入的方式有4种:

  • setter方法注入:通过调用setter方法注入属性

  • 构造方法注入/构造器注入:通过调用构造方法注入属性

  • 方法注入:通过调用普通的方法注入属性

  • 字段注入/属性注入:不需要调用方法就能完成注入

自动注入

自动注入指的是Spring对一个bean中的依赖的自动处理。

什么是依赖:一个Bean作为另外一个Bean的成员变量。

Spring有以下4种自动注入模式。

  • no:不自动注入(默认)

  • byType:通过类型注入,如果在当前IOC容器中有一个对应类型的Bean就会自动注入

  • byName:通过属性名自动注入

  • constructor:通过类型进行注入,但是要作为构造方法的参数

Spring默认是不会帮我们注入一个bean中的属性的,所以需要告诉Spring哪些属性需要进行注入。

配置文件

可以在xml配置文件中定义元配置(metadata configuration),通过beans标签的子标签bean及其子标签配置Bean的定义

beans标签

beans标签的标准格式如下:

<?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">

</beans>

<beans>标签上可以指定其<bean>子标签的默认属性:

标签属性属性说明取值范围
default-lazy-init默认的懒加载配置true、false
default-autowire默认的自动注入方式no、byType、byName、constructor
default-init-method默认的初始化方法任意方法名
default-destroy-method默认的销毁方法任意方法名

关于懒加载:

懒加载的bean只有第一次被访问时才会被Spring IOC容器创建。

在容器启动时不会创建懒加载的bean,直到第一次通过IOC容器获取使用这个bean。

bean标签

bean标签是beans标签的直接子标签,用来将一个类定义为Spring Bean。

bean标签上可以指定很多属性:

属性名属性说明默认值取值说明/取值范围
idbean ID任意的字符串,建议类名首字母小写
namebean名称任意的字符串,建议类名首字母小写
classbean的类型类的全限定名
scopebean的作用域singletonsingleton、prototype
autowire自动注入方式nono、byType、byName、constructor
lazy-init是否懒加载falsetrue、false
init-methodbean初始化完成调用的方法任意的方法名
depends-on依赖的Bean,被依赖的Bean会在当前Bean之前创建任意bean名称
factory-bean指定用于实例化bean的工厂Bean任意bean名称
factory-method指定用于实例化bean的工厂方法任意方法的方法名
destroy-methodbean销毁时调用的方法任意的方法名

实例化Bean

通过构造方法实例化

Spring IOC容器默认就是使用构造方法进行实例化的。

通过静态方法实例化

可以通过<bean/>的factory-method属性指定使用当前bean中定义的一个静态方法进行实例化(创建Bean对象)。

既然是用来创建对象的,这个静态方法的返回值类型就应该是Bean的类型。

package cn.edu.sgu.www.beans;

import java.util.ArrayList;
import java.util.List;

/**
 * @author heyunlin
 * @version 1.0
 */
public class UserDao {

    public static UserDao newInstance() {
        System.out.println("调用UserDao.newInstance()...");
        
        return new UserDao();
    }

    public List<String> selectAll() {
        List<String> list = new ArrayList<>();

        list.add("Tom");
        list.add("Jhon");
        list.add("Marry");

        return list;
    }

}

比如通过上面UserDao的newInstance()方法进行实例化。

<?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="userDao" class="cn.edu.sgu.www.beans.UserDao" factory-method="newInstance"/>
</beans>

通过实例方法实例化

需要同时使用<bean/>的factory-bean和factory-method属性配置使用指定bean中定义的一个实例方法进行实例化(创建Bean对象)。

package cn.edu.sgu.www.beans;

/**
 * @author heyunlin
 * @version 1.0
 */
public class BeanInitializer {

    public UserDao newUserDao() {
        System.out.println("调用BeanInitializer.newUserDao()...");
        
        return new UserDao();
    }

}

比如通过上面的BeanInitializer的newUserDao()方法实例化bean

<?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="beanInitializer" class="cn.edu.sgu.www.beans.BeanInitializer" />

    <bean id="userDao" class="cn.edu.sgu.www.beans.UserDao"
          factory-bean="beanInitializer" factory-method="newUserDao"/>
</beans>

Bean的作用域

Bean的作用域(Scope)又叫Bean的作用范围,比如变量也有作用范围:成员变量(全局变量)、局部变量。

Spring中的bean默认都是单例(singleton)的。

  • 通过BeanFactory获取到的bean始终是同一个

  • Bean的作用范围是整个IOC容器

单例Bean的实现原理:

要实现这个效果,需要是用到软件设计模式中的单例模式(Singleton Desgn Pattern),就是将类的构造方法全部设置为私有,然后定义一个public的静态方法用于创建对象的实例。这个public的静态方法通常取名为newInstance()。

为什么是静态方法呢?构造方法被设置成了private,就无法去new对象了,所以就无法调用实例方法。

Spring中的作用域有以下几个:常用的就只有前两个。

作用域说明
singleton全局单例
prototype原型(多例),每次通过BeanFactory的getBean()方法获取到的bean都是一个新的对象
request一次HTTP请求就会创建一个Bean的实例
session一次session会话就会创建一个Bean的实例
application在一个应用中是单例的
websocket在一次WebSocket连接中是单例的

BeanDefinition

BeanDefinition叫做Bean的定义,保存了Bean的信息(名称、类型等)

beans标签的所有bean子标签都会被解析为一个BeanDefinition对象。

这个接口中定义了大量和bean标签属性对应的许多getter、setter方法。

package org.springframework.beans.factory.config;

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    // 和bean标签属性对应的许多getter、setter方法...
}

AbstractBeanDefinition

BeanDefinition是一个接口,实际使用的是其派生类AbstractBeanDefinition。

package org.springframework.beans.factory.support;

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {
    
    @Nullable
	private volatile Object beanClass; // class
    
    @Nullable
	private String scope = SCOPE_DEFAULT; // scope
    
    @Nullable
	private Boolean lazyInit; // lazy-init
    
    private int autowireMode = AUTOWIRE_NO; // autowire
    
    @Nullable
	private String[] dependsOn; // depends-on
    
    private boolean autowireCandidate = true; // autowire-candidate
    
    private boolean primary = false; // primary
    
    @Nullable
	private String factoryBeanName; // factory-bean

	@Nullable
	private String factoryMethodName; // factory-method
    
    @Nullable
	private String initMethodName; // init-method

	@Nullable
	private String destroyMethodName; // destroy-method
    
    // 其他属性...
    
    // getter、setter方法...
}

Spring IOC容器会根据这些BeanDefinition对象来创建Bean,然后保存起来。

在容器启动完成后,就可以通过代表IOC容器的接口BeanFactory、ApplicationContext获取bean了。

回调接口

Spring提供了大量和bean的生命周期相关的回调接口。

Aware

Aware是Spring的回调接口,Aware接口有很多的子接口,这些接口下通常就定义了一个set方法。

BeanNameAware

可以通过BeanNameAware获取Bean名称。

package org.springframework.beans.factory;

public interface BeanNameAware extends Aware {
    
    /**
     * 设置Bean名称
     */
    void setBeanName(String name);
}

BeanFactoryAware

可以通过BeanFactoryAware获取BeanFactory。

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

public interface BeanFactoryAware extends Aware {
    
    /**
     * 设置BeanFactory
     */
    void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

ApplicationContextAware

可以通过ApplicationContextAware获取ApplicationContext。

package org.springframework.context;

import org.springframework.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {
    
    /**
     * 设置ApplicationContext
     */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

ApplicationEventPublisherAware

可以通过ApplicationEventPublisherAware获取ApplicationEventPublisher(事件发布器)。

package org.springframework.context;

import org.springframework.beans.factory.Aware;

public interface ApplicationEventPublisherAware extends Aware {	
	void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}

InitializingBean

InitializingBean叫做初始化bean,是Spring的bean初始化回调接口。

通过InitializingBean,可以在bean初始化完成(通过自动注入设置完属性)后,对bean进行一些操作。

package org.springframework.beans.factory;

public interface InitializingBean {
    
    void afterPropertiesSet() throws Exception;
}

接下来自定义一个InitializingBean,在所有bean初始化完成后打印提示。

package cn.edu.sgu.www.beans;

import org.springframework.beans.factory.InitializingBean;

/**
 * @author heyunlin
 * @version 1.0
 */
public class CutomInitializingBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        System.out.println("完成属性注入...");
    }

}

这个接口的作用和bean标签通过init-method属性指定方法是一样的。

DisposableBean

DisposableBean叫做销毁bean,是Spring的bean销毁回调接口。

package org.springframework.beans.factory;

public interface DisposableBean {
    
	void destroy() throws Exception;
}

通过DisposableBean,可以在bean被销毁后执行一些操作。

这个接口的作用和bean标签通过destroy-method属性指定方法是一样的。

容器扩展

BeanPostProcessor

BeanPostProcessor叫做bean的后置处理器,通过BeanPostProcessor可以在bean实例化过程中对bean进行修改。

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

public interface BeanPostProcessor {
    
    @Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
    
    @Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

BeanPostProcessor接口中定义了两个默认的方法(根据需要重写)

  • postProcessBeforeInitialization()

  • postProcessAfterInitialization()

postProcessBeforeInitialization()

在bean实例化之前对bean进行修改。

postProcessAfterInitialization()

在bean实例化之后对bean进行修改。

自定义BeanPostProcessor

自定义一个BeanPostProcessor完成bean的属性的设置(类似依赖注入)。

package cn.edu.sgu.www.beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.lang.reflect.Field;

/**
 * @author heyunlin
 * @version 1.0
 */
public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userController".equals(beanName)) {
            Field[] fields = bean.getClass().getDeclaredFields();

            for (Field field : fields) {
                field.setAccessible(true);

                try {
                    Object value = field.get(bean);
                    Object instance = field.getType().newInstance();

                    if (value == null) {
                        field.set(bean, instance);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}

这种方式是直接通过反射创建bean对象,而不是通过BeanFactory获取。

执行postProcessBeforeInitialization()方法时所有bean都还没有完成初始化。

BeanFactoryPostProcessor

BeanFactoryPostProcessor叫做bean工厂的后置处理器,通过BeanFactoryPostProcessor可以修改bean的定义。

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

BeanFactoryPostProcessor的执行时机是,所有bean的定义都已经加载完成,但是还没有实例化。

使用IOC容器

创建项目

在Intellij IDEA中创建一个maven项目spring-study

添加依赖

使用Spring的IOC/DI特性需要引入spring-beans和spring-context两个依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.edu.sgu.www</groupId>
    <artifactId>spring-study</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>
    </dependencies>
</project>

创建对象

在项目的src/java目录下创建多级包cn.edu.sgu.www

在cn.edu.sgu.www包下创建beans包

UserDao.java

在beans包下创建一个类UserDao

package cn.edu.sgu.www.beans;

import java.util.ArrayList;
import java.util.List;

/**
 * @author heyunlin
 * @version 1.0
 */
public class UserDao {

    public List<String> selectAll() {
        List<String> list = new ArrayList<>();

        list.add("Tom");
        list.add("Jhon");
        list.add("Marry");

        return list;
    }

}

UserService.java

在beans包下创建一个类UserService

package cn.edu.sgu.www.beans;

import java.util.List;

/**
 * @author heyunlin
 * @version 1.0
 */
public class UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public List<String> selectAll() {
        return userDao.selectAll();
    }

}

UserController.java

在beans包下创建一个类UserController

package cn.edu.sgu.www.beans;

import java.util.List;

/**
 * @author heyunlin
 * @version 1.0
 */
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    public List<String> selectAll() {
        return userService.selectAll();
    }

}

创建配置文件

在类路径(resouces)目录下创建一个beans目录,然后在bean目录下Spring的xml配置文件。

daos.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="userDao" class="cn.edu.sgu.www.beans.UserDao" />
</beans>

services.xml

通过UserService配置依赖注入(setter注入)

<?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="userService" class="cn.edu.sgu.www.beans.UserService">
        <property name="userDao" ref="userDao" />
    </bean>
</beans>

注意,使用setter注入方式时,需要保证对应的bean上声明了无参构造方法和对应属性的setter方法。

controllers.xml

通过UserController配置依赖注入(构造方法注入)

<?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="userController" class="cn.edu.sgu.www.beans.UserController">
        <constructor-arg ref="userService" type="cn.edu.sgu.www.beans.UserService" />
    </bean>
</beans>

注意,使用构造方法注入方式时,需要保证对应的bean上声明了对应属性的有参构造方法。

通过IOC容器获取Bean

IOC容器相关接口
BeanFactory

BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。

其中,有几个重载的getBean()方法可以从Spring IOC容器中获取bean。

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

public interface BeanFactory {
    
    /**
     * 通过bean名称获取bean
     */
    Object getBean(String name) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;

    /**
     * 通过bean的类型获取bean
     */
    <T> T getBean(Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    /**
     * 通过bean名称和类型获取bean
     */
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
}

和BeanFactory接口名字及其相似的一个接口FactoryBean,叫做工厂bean。

工厂bean通常作为一个bean工厂,负责创建bean对象。

package org.springframework.beans.factory;

public interface FactoryBean<T> {
    
    Class<?> getObjectType();
    
    T getObject() throws Exception;
    
    default boolean isSingleton() {
		return true;
	}
}

ApplicationContext

ApplicationContext是BeanFactory的子接口。

package org.springframework.context;

import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    
    @Nullable
	String getId();
    
    /**
     * 获取启动时间
     */
    long getStartupDate();
    
    /**
     * 获取当前应用上下文的名称
     */
    String getDisplayName();
    
     /**
     * 获取应用名称
     */
    String getApplicationName();
    
    /**
     * 获取上一级应用上下文
     */
    @Nullable
	ApplicationContext getParent();
    
    /**
     * 获取AutowireCapableBeanFactory
     */
    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

相比于BeanFactory,ApplicationContext中新增了以下功能:

  • 更容易与Spring的AOP功能集成

  • 消息资源处理(用于国际化internationalization, i18n)——实现了MessageSource接口

  • 事件发布——实现了ApplicationEventPublisher接口

  • 特定于应用层的上下文(ApplicationContext提供的不同应用场景下使用的派生类)

    • 比如Web应用程序中使用的WebApplicationContext

ApplicationContext有以下几个常用的派生类:

ClassPathXmlApplicationContext

ClassPathXmlApplicationContext用于通过类路径(classpath)下的xml配置文件创建ApplicationContext对象。

使用ClassPathXmlApplicationContext时,只需要指定相对于项目的src/main/resources路径下的文件位置。

例如:通过src/main/resources/beans.xml配置文件创建ApplicationContext对象。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml");

FileSystemXmlApplicationContext

用于通过文件系统的xml配置文件创建ApplicationContext对象,通过FileSystemXmlApplicationContext可以加载项目外的xml文件。

使用FileSystemXmlApplicationContext时,需要指定xml文件的绝对路径(因此,可以加载项目外的配置文件)。

String path = "D:/program/IdeaProjects/spring-study/src/main/resources/bean/beans.xml";

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(path);

AnnotationConfigApplicationContext

用于通过配置类创建ApplicationContext对象,后面使用注解方式配置Bean的时候会讲。

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CustomConfig.class);

通过BeanFactory获取Bean

在cn.edu.sgu.www包下创建XmlBasedSpringExample类,用来写获取Bean的Java代码。

获取UserDao
package cn.edu.sgu.www;

import cn.edu.sgu.www.beans.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author heyunlin
 * @version 1.0
 */
public class XmlBasedSpringExample {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userDao");

        if (bean instanceof UserDao) {
            UserDao userDao = (UserDao) bean;

            System.out.println(userDao.selectAll());
        }

        // 通过类型获取Bean
        UserDao userDao = applicationContext.getBean(UserDao.class);

        System.out.println(userDao.selectAll());
    }

}

获取UserService
package cn.edu.sgu.www;

import cn.edu.sgu.www.beans.UserDao;
import cn.edu.sgu.www.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author heyunlin
 * @version 1.0
 */
public class XmlBasedSpringExample {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml", "bean/services.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userService");

        if (bean instanceof UserService) {
            UserService userService = (UserService) bean;

            System.out.println(userService.selectAll());
        }

        // 通过类型获取Bean
        UserService userService = applicationContext.getBean(UserService.class);

        System.out.println(userService.selectAll());
    }

}

获取UserController
package cn.edu.sgu.www;

import cn.edu.sgu.www.beans.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author heyunlin
 * @version 1.0
 */
public class XmlBasedSpringExample {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml", "bean/services.xml", "bean/controllers.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userController");

        if (bean instanceof UserController) {
            UserController userController = (UserController) bean;

            System.out.println(userController.selectAll());
        }

        // 通过类型获取Bean
        UserController userController = applicationContext.getBean(UserController.class);

        System.out.println(userController.selectAll());
    }

}

获取所有Spring Bean
package cn.edu.sgu.www;

import cn.edu.sgu.www.beans.UserController;
import cn.edu.sgu.www.beans.UserDao;
import cn.edu.sgu.www.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author heyunlin
 * @version 1.0
 */
public class XmlBasedSpringExample {

    public static void main(String[] args) {
        getUserDao();
        getUserService();
        getUserController();
    }

    private static void getUserDao() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userDao");

        if (bean instanceof UserDao) {
            UserDao userDao = (UserDao) bean;

            System.out.println(userDao.selectAll());
        }

        // 通过类型获取Bean
        UserDao userDao = applicationContext.getBean(UserDao.class);

        System.out.println(userDao.selectAll());
    }

    private static void getUserService() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml", "beans/services.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userService");

        if (bean instanceof UserService) {
            UserService userService = (UserService) bean;

            System.out.println(userService.selectAll());
        }

        // 通过类型获取Bean
        UserService userService = applicationContext.getBean(UserService.class);

        System.out.println(userService.selectAll());
    }

    private static void getUserController() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/daos.xml", "beans/services.xml", "beans/controllers.xml");

        // 通过Bean名称获取Bean
        Object bean = applicationContext.getBean("userController");

        if (bean instanceof UserController) {
            UserController userController = (UserController) bean;

            System.out.println(userController.selectAll());
        }

        // 通过类型获取Bean
        UserController userController = applicationContext.getBean(UserController.class);

        System.out.println(userController.selectAll());
    }

}


http://www.kler.cn/a/585792.html

相关文章:

  • JVM 如何保证 Java 程序的安全性?
  • TypeScript 高级类型 vs JavaScript:用“杂交水稻”理解类型编程
  • 【redis】set 类型:基本命令
  • 遥感数据获取、处理、分析到模型搭建全流程学习!DeepSeek、Python、OpenCV驱动空天地遥感数据分析
  • WPF程序使用AutoUpdate实现自动更新
  • Secs/Gem第一讲(基于secs4net项目的ChatGpt介绍)
  • 完善机器人:让 DeepSeek 使用Vue Element UI快速搭建 AI 交互页面
  • 【Linux系统编程】管道
  • 什么是mysql索引回表?
  • 杨辉三角形(信息学奥赛一本通-2043)
  • 智慧应急消防解决方案(35页PPT)(文末有下载方式)
  • doris:SQL 方言兼容
  • 【0x80070666】-已安装另一个版本...(Tableau 安装失败)
  • 裸机开发-GPIO外设
  • Android的第一次面试(Java篇)
  • 为什么 JPA 可以通过 findByNameContaining 自动生成 SQL 语句?
  • 如何在PHP中实现数据加密与解密:保护敏感信息
  • 小语言模型(SLM)技术解析:如何在有限资源下实现高效AI推理
  • 《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》:此文为AI自动生成
  • Windows 上安装配置 Maven