admin管理员组

文章数量:1794759

从Bean的装配理解Spring框架

从Bean的装配理解Spring框架

阅读此文前,可以参考这篇文章: Spring源码解析


基于XML装配Bean

applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="www.springframework/schema/beans" xmlns:xsi="www.w3/2001/XMLSchema-instance" xsi:schemaLocation="www.springframework/schema/beans www.springframework/schema/beans/spring-beans.xsd"> <bean id="helloSpring" class="com.gjf.HelloSpring"> <!--id表示bean实例的名称 class是这个bean的类型,也是需要实例化bean的类--> <!--将value的值赋值给who属性"/>--> <property name="who" value="Spring"/> </bean> </beans>
  • 可以通过ClassPathXmlApplicationContext加载applicationContext.xml文件
  • public class HelloSpringTest { @Test public void test() { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloSpring helloSpring = (HelloSpring)applicationContext.getBean("helloSpring"); helloSpring.print(); } }
  • 看ClassPathXmlApplicationContext源码
  • /** 独立的XML应用程序上下文,从类路径中获取上下文定义文件 是一个简单的一站式便利ApplicationContext */ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { @Nullable private Resource[] configResources; /** 为bean样式的配置创建一个新的ClassPathXmlApplicationContext * @see #setConfigLocation * @see #setConfigLocations * @see #afterPropertiesSet() */ public ClassPathXmlApplicationContext() { } /** 创建一个新的ClassPathXmlApplicationContext, 从给定的XML文件中加载定义,并自动刷新上下文。 * @param configLocation resource location * @throws BeansException if context creation failed */ public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); }

    ClassPathXmlApplicationContext的UML关系图,如果读过spring的源码,可能发现很多熟悉的类或者接口;

    可以参考这篇文章:Spring源码解析

    如BeanFactory接口:Spring的IOC容器核心接口,它的职责包括,实例化,有很多的实现类;

    如ApplicationContext接口:用于访问应用程序组件的Bean工厂方法,以通用方式加载文件资源的能力等

    (Spring的上下文,我简单理解就是spring的当前运行的环境,也可以理解是spring可以利用的资源。)

    ApplicationContext有两个主要的实现类:ClassPathXmlApplicationContext:默认从类路径加载配置文件,还有FileSystemXmlApplicationContext:默认从文件系统中装载配置文件

    理清spring创建定制Bean的整个过程

    Bean的装配方式:

  • 基于XML的装配
  • 基于注解的装配
  • 自动装配
  • <!--创建Bean的三种方式 --> <!-- 第一种方式:使用默认构造函数创建。 在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。 采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。 <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean> --> <!-- 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器) <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean> --> <!-- 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器) <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean> --> <!-- bean的作用范围调整 bean标签的scope属性: 作用:用于指定bean的作用范围 取值: 常用的就是单例的和多例的 singleton:单例的(默认值) prototype:多例的 request:作用于web应用的请求范围 session:作用于web应用的会话范围 global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"></bean> -->

    创建实例对象不在是调用者来创建而是交给spring(控制反转),在Spring框架实例化Bean的过程中,首先调用Bean默认的构造方法来实例化Bean对象,然后通过反射的方式调用setter方法注入属性值(依赖注入)

    依赖注入时,要求Bean必须满足下列要求

  • 提供一个默认的无参构造方法
  • 需要为注入的属性提供对应的setter方法

  • 基于注解装配Bean

    减少xml文件的使用,引入注解

    Spring常用的注解 定义bean的注解说明
    @Component描述spring中的bean
    @Repository用于数据访问层(Dao),标识为spring的bean,功能与@Component相似
    @Service通常用于业务层(Service层),将类标识为spring的bean,功能与@Component相似
    @Controller通常作用于控制层(Controller层),将类标识为spring的bean,功能与@Component相似
    • 找@Repository的源码看看
    @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Repository { /** 该值可能表示建议使用逻辑组件名称,如果是自动检测到的组件, 则将其转换为Spring bean. */ @AliasFor(annotation = Component.class) String value() default ""; } Bean组件装配注解说明
    @Autowired用于对bean的属性变量,构造方法进行标注,按照默认bean的类型完成自动配置工作
    @Resource用于对bean的属性变量,构造方法进行标注,按照默认bean的实例名称完成自动配置工作
    @Qualifier与@Autowired配合使用,会默认的按bean类型装配修改为按实例名称装配,实例名称由@Qualifier参数指定
    //@Autowired事例 @Service("userService") public class UserServiceImpl implements UserService { @Autowired //默认按照类型匹配 private UserDao userDao; /* @Override 使用@Autowired 直接注入属性,可以省略setter方法 public void setUserDao(UserDao userDao) { this.userDao = userDao; }*/ }
    • 点进@Autowired,AutowiredAnnotationBeanPostProcessor 进去看
    /* @author Juergen Hoeller * @author Mark Fisher * @author Sam Brannen * @since 2.5 * @see AutowiredAnnotationBeanPostProcessor //see see看 * @see Qualifier * @see Value */ @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { boolean required() default true; } /** 为Spring的标准{@link Autowired @Autowired}和 {@link Value @Value}注释创建一个新的{@code AutowiredAnnotationBeanPostProcessor} 还支持JSR-330的{@link javax.inject.Inject @Inject}批注(如果可用) */ @SuppressWarnings("unchecked") public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); try { this.autowiredAnnotationTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } } /** 设置“自动装配”注释类型,以用于构造函数,字段,setter方法和任意配置方法。 默认的自动装配注释类型是Spring提供的{@link Autowired @Autowired}和{@link Value @Value}注释以及 JSR-330的{@link javax.inject.Inject @Inject}注释, 如果可供使用的话。 * <p>存在此setter属性,以便开发人员可以提供自己的*(非特定于Spring的)批注类型,以指示应该自动装配成员。 */ public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) { Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null"); this.autowiredAnnotationTypes.clear(); this.autowiredAnnotationTypes.add(autowiredAnnotationType); }

    发现什么?spring真强大!哈哈哈!

    {@link Autowired @Autowired}和{@link Value @Value}注释创建一个新的{@code AutowiredAnnotationBeanPostProcessor},熟悉的:BeanPostProcessor

    就讲这些吧,希望可以给初学Spring的猿提供捷径吧 一键三连收藏


    本文标签: 框架beanspring