Spring 基础与应用 详解

Spring 基础与应用

一、什么是Spring?

Spring是分层的JavaSE/EE full-stack 轻量级开源框架,以IoC(Inverse of Control 控制反转)和AOP(Aspect Oriented Programming 面向切面编程)为内核,使用基本的JavaBean来完成以前只可能由EJB完成的工作,取代了EJB的臃肿、低效的开发模式。
在实际开发中,通常服务器端在采用三层体系架构,分别为表示层(Web)、业务逻辑层(Service)、持久层(Dao), Spring对每一层都提供了技术支持。

二、Spring的优点

Spring具有简单、可测试和松耦合等特点。Spring不仅可以用于服务器端开发,也可以应用于任何Java应用的开发中。

  1. 方便解耦、简化开发
  2. 支持AOP 支持声明式事务处理
  3. 方便程序测试
  4. 方便集成各种优秀框架
  5. 降低Java EE API的使用难度
  6. 非侵入式设计

三、Spring的体系结构

Spring框架采用的是分层架构,它一系列的功能要素被分成20个模块。
在这里插入图片描述

四、Spring的核心容器

Spring容器会负责控制程序之间的关系,而不是由程序代码直接控制。Spring为我们提供了两种核心容器,分别为BeanFactory和ApplicationContext

1、BeanFactory

BeanFactory提供了实例化对象和拿对象的功能;
创建BeanFactory实例时,需要提供Spring所管理容器的详细配置信息,这些信息通常采用XML文件形式来管理,其加载配置信息的语法如下:

BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("xml文件路径"));

2、ApplicationContext

ApplicationContext是BeanFactory的子接口,是另一种常用的Spring核心容器。应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能

  1. 国际化(MessageSource)
  2. 访问资源,如URL和文件(ResourceLoader)
  3. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
  4. 消息发送、响应机制(ApplicationEventPublisher)
  5. AOP(拦截器)
    创建ApplicationContext接口实例,通常采用两种方法,具体如下:
1.通过ClassPathXmlApplicationContext创建

ClassPathXmlApplicationContext会从类路径classPath中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作

ApplicationContext  applicationContext = new ClassPathXmlApplicationContext(String configLocation);
2.通过FileSystemXmlApplicationContext创建

FileSystemXmlApplicationContext会从指定的文件系统路径(绝对路径)中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);
3.通过ContextLoaderListener创建

在Java项目中,会通过ClassPathXmlApplicationContext类来实例化ApplicationContext容器。而在Web项目中,ApplicationContext容器的实例化工作会交由Web服务器来完成。
Web服务器实例化ApplicationContext容器时,通常会使用ContextLoaderListener来实现,此种方式只需要在web.xml中添加如下代码:

<context-param>
    <param-name>contextConfigLocation</param-name> 
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param> 
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
BeanFactory 与 ApplicationContext装载Bean的区别

BeanFactory:
BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;
应用启动的时候占用资源很少;对资源要求较高的应用,比较有优势;
ApplicationContext:
ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;

  1. 所有的Bean在启动的时候都加载,系统运行的速度快;
  2. 在启动的时候所有的Bean都加载了,我们就能在系统启动的时候,尽早的发现系统中的配置问题
  3. 建议web应用,在启动的时候就把所有的Bean都加载了。(把费时的操作放到系统启动中完成)

3.获取Bean的实例的两种方法

1.Object getBean(String name);
根据容器中Bean的id或name来获取指定的Bean,获取之后需要进行强制类型转换。
2. T getBean(Class requiredType);
根据类的类型来获取Bean的实例。由于此方法为泛型方法,因此在获取Bean之后不需要进行强制类型转换。

ApplicationContext applicationContext = new  ClassPathXmlApplicationContext(String configLocation);
//applicationContext.getBean("bean的Id");
applicationContext.getBean(xxxBean.class);

五、依赖注入

1.依赖注入的概念

DI的全称是Dependency Injection,中文称之为依赖注入。它与控制反转(IoC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。在Spring的源码中有讲到IoC is also known as dependency injection (DI);【IOC也被称为依赖注入】所以IOC和DI本质上是同一个概念。
依赖的概念:假如A类中有一个B类的属性,那么A类就依赖了B类
注入的概念:容器将被依赖的对象注入到依赖的对象的过程

1.IoC

在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到了Spring容器,控制权发生了反转,这就是控制反转。

2.DI

从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。

2.Spring依赖注入的三种方式

在Spring容器中为一个bean配置依赖注入有三种方式:
· 使用属性的setter方法注入
· 使用构造器注入;
· 使用Filed注入(用于注解方式)

1.使用属性的setter方法注入

使用setter方法注入时,需要给属性定义set方法;

public class User{
	
	private String name;
	private int age;

	public void setName(String name){
		this.name = name;
	}
}
<bean id="User" class="com.wwx.User">  
    <property name="name" value="wuwei"/>  
    <property name="age" value="18"/>  
    ……  
</bean>

注意:在User中没有定义构造器,则JVM自动为其生成一个默认的构造函数。若在User中定义了有参的构造函数,则需定义一个无参的构造函数,否则注入时会抛出异常。

2.使用构造器注入

构造函数注入是除属性注入之外的另一种常用的注入方式,它保证一些必要的属性在Bean实例化时就得到设置(construct是bean生命周期的第一步,实例化bean),并且确保了Bean实例在实例化后就可以使用。

在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了节点,该节点有四个属性:
· index是索引,指定注入的属性,从0开始;
· type是指该属性所对应的类型,如UserDao对应的是com.wwx.dao.UserDao;
· ref 是指引用的依赖对象;
· value 当注入的不是依赖对象,而是基本数据类型时,就用value;

public class UserServiceImpl interface UserService{
	private UserDao userDao;
	private String userName;
	//提供构造方法
	public UserServiceImpl(){}
	public UserServiceImpl (UserDao userDao,String userName){
		this.userDao = userDao;
		this.userName = userName;
	}
}
<!-- 利用构造器配置依赖注入 -->
<bean id="userDao" class="com.wwx.dao.UserDao"></bean>
<bean id="UserService" class="com.wwx.service.impl.UserServiceImpl ">
<constructor-arg index="0" type="com.wwx.dao.UserDao"ref="userDao"></constructor-arg>
<constructor-arg index="1" value="Spring学习"></constructor-arg>
</bean>
3.使用Field注入(用注解注入)

装配方式有4种:name、type、constructor、autodetect
具体选择哪一种装配方式,需要配置标签的autowire属性,如果没有配置,默认是byName类型,就是会根据属性的名字来进行自动装配。
1)name就是会将与属性的名字一样的bean进行装配。
2)type就是将同属性一样类型的bean进行装配。
3)constructor就是通过构造器来将类型与参数相同的bean进行装配。
4)autodetect是constructor与byType的组合,会先进行constructor,如果不成功,再进行byType。
使用注解方式注入的具体步骤:
(1)在Spring容器的配置文件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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">

注意:只有配置了红色部分的代码才可以引入注解的命名空间,否则报错。 以上的配置隐式的注册了多个对注释进行解析的处理器:AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor等。
(2)在配置文件中打开context:annotation-config节点

<beans>
<context:annotation-config></context:annotation-config>
</beans>

(3)在配置文件中配置bean

<bean id="userDao" class="com.wwx.dao.impl.UserDao"></bean>
<bean id="userService" class="com.wwx.dao.impl.UserServiceImpl"></bean>

(4)给声明的依赖对象加注解

public class UserServiceImpl interface UserService{
	@Autowired
	@Qualifier("userDao")
	//@Resource("userDao")	
	private UserDao userDao;
	public void test(){
	}
}

使用@Autowired或@Resource区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
@Autowired和@Qualifier("…")可以同时使用,利用@Qualifier("…")指定特定的被依赖对象的名称。

补充:常用的注入注解有@Autowired,@Qualifier,@Named,@Resource,@Inject;(关于@Inject自定义注解会在后面的文章详细讲)

六、自动装配

Spring容器可以自动装配协作bean之间的关系。
自动装配具有以下优点:
(1)自动装配可以大大减少指定属性或构造函数参数的需要。
(2)随着对象的发展,自动装配可以更新配置。例如,如果您需要向类中添加依赖项,则无需修改配置即可自动满足该依赖项。
因此,自动装配在开发过程中特别有用,而不必担心在代码库变得更稳定时切换到显式接线的选择。
自动装配分为以下4种模式:(4种自动装配模型)

模式说明
no(默认)无自动装配。Bean引用必须由ref元素定义。对于较大的部署,建议不要更改默认设置,因为明确指定协作者可以提供更好的控制和清晰度。在某种程度上,它记录了系统的结构。
byName按属性名称自动布线。Spring寻找与需要自动装配的属性同名的bean。例如,如果一个bean定义被设置为按名称自动装配并且包含一个master属性(即它具有一个 setMaster(…)方法),那么Spring将查找一个名为的bean定义,master并使用它来设置该属性。
byType如果容器中恰好存在一个属性类型的bean,则使该属性自动连接。如果存在多个错误,则会引发致命异常,这表明您可能无法byType对该bean 使用自动装配。如果没有匹配的bean,则什么都不会发生(未设置该属性)。
constructor类似于byType但适用于构造函数参数。如果容器中不存在构造函数参数类型的一个bean,则将引发致命错误。

接下来准备继续更新Spring其他知识的文章(包括源码详解)~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值