从Bean的装配理解Spring框架
Posted JF Coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Bean的装配理解Spring框架相关的知识,希望对你有一定的参考价值。
阅读此文前,可以参考这篇文章:
Spring源码解析
基于XML装配Bean
applicationContext.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
http://www.springframework.org/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的猿提供捷径吧
一键三连收藏
以上是关于从Bean的装配理解Spring框架的主要内容,如果未能解决你的问题,请参考以下文章