三层架构:
表现层 web层 MVC是表现层的一个设计模型
业务层 service层
持久层 dao层
Spring IoC容器
- Spring容器时Spring框架的核心。
- 容器将创建对象(被称为 Spring Beans),把它们连接在一起,配置它们,并管理他们的整个生命周期。
- Spring容器使用依赖注入(DI)来管理组成一个应用程序的组件。
控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。
在Spring中BeanFactory是IOC容器的实际代表者。
Spring 提供了以下两种不同类型的容器。
1 Spring BeanFactory 容器
它是最简单的容器,给 DI 提供了基本的支持,它用org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。
最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
2 Spring ApplicationContext 容器
该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。
最常被使用的 ApplicationContext 接口实现:
FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
ApplicationContext 容器包括 BeanFactory 容器的所有功能。
Spring Bean
属性 | 描述 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类。 |
name | 这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。 |
scope | 这个属性指定由特定的 bean 定义创建的对象的作用域 |
constructor-arg | 它是用来注入依赖关系的 |
properties | 它是用来注入依赖关系的 |
autowiring mode | 它是用来注入依赖关系的 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法。 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法。 |
有下面三个重要的方法把配置元数据提供给 Spring 容器:
- 基于 XML 的配置文件
- 基于注解的配置
- 基于 Java 的配置
Spring Bean 作用域:
作用域 | 描述 |
---|---|
singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean() |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境 |
global-session | 一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境 |
Spring Bean生命周期
在基于 XML 的配置元数据的情况下,使用 init-method 属性来指定带有 void 无参数方法的名称。
<bean id="exampleBean"
class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {
public void init() {
// do some initialization work
}
}
在基于 XML 的配置元数据的情况下,使用 destroy-method 属性来指定带有 void 无参数方法的名称。
<bean id="exampleBean"
class="examples.ExampleBean" destroy-method="destroy"/>
public class ExampleBean {
public void destroy() {
// do some destruction work
}
}
如果你有太多具有相同名称的初始化或者销毁方法的 Bean,那么不需要在每一个 bean 上声明初始化方法和销毁方法。框架使用 元素中的 default-init-method 和 default-destroy-method 属性提供了灵活地配置这种情况。
<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-3.0.xsd"
default-init-method="init"
default-destroy-method="destroy">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
Spring Bean后置处理器
BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。
ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。
Spring 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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>
<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
</beans>
创建一个 Bean 定义模板:在定义一个 Bean 定义模板时,不应该指定类的属性,而应该指定带 true 值的抽象属性。
<?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-3.0.xsd">
<bean id="beanTeamplate" abstract="true">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
<property name="message3" value="Namaste India!"/>
</bean>
<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
</beans>
Spring依赖注入(DI)
通过依赖注入的方式来管理Bean之间的依赖关系。
基于构造函数进行依赖注入:
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
package x.y;
public class Foo {
public Foo(Bar bar, Baz baz) {
// ...
}
}
<beans>
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
</bean>
<bean id="bar" class="x.y.Bar"/>
<bean id="baz" class="x.y.Baz"/>
</beans>
使用 index 属性来显式的指定构造函数参数的索引:
<beans>
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="2001"/>
<constructor-arg index="1" value="Zara"/>
</bean>
</beans>
如果想要向一个对象传递一个引用,需要使用标签的 ref 属性,如果要直接传递值,那么使用 value 属性。
基于设值函数的依赖注入
依赖注入的第二种方法是通过 TextEditor 类的 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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker" ref="spellChecker"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
</beans>
基于构造函数注入和基于设值函数注入中的 Beans.xml 文件的区别:
唯一的区别就是在基于构造函数注入中,我们使用的是
〈bean〉标签中的〈constructor-arg〉元素,而在基
于设值函数的注入中,我们使用的是〈bean〉标签中的
〈property〉元素。
使用 p-namespace 实现 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-3.0.xsd">
<bean id="john-classic" class="com.example.Person">
<property name="name" value="John Doe"/>
<property name="spouse" ref="jane"/>
</bean>
<bean name="jane" class="com.example.Person">
<property name="name" value="John Doe"/>
</bean>
</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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="john-classic" class="com.example.Person"
p:name="John Doe"
p:spouse-ref="jane"/>
</bean>
<bean name="jane" class="com.example.Person"
p:name="John Doe"/>
</bean>
</beans>
Spring注入集合
集合的配置元素 | 描述 |
---|---|
< list> | 它有助于连线,如注入一列值,允许重复 |
< set> | 它有助于连线一组值,但不能重复 |
< map> | 它可以用来注入名称-值对的集合,其中名称和值可以是任何类型 |
< props> | 它可以用来注入名称-值对的集合,其中名称和值都是字符串类型 |
可以使用<list>或<set>来连接任何 java.util.Collection 的实现或数组
Spring自动装配
模式 | 描述 |
---|---|
no | 默认没有自动装配 |
byName | 由属性名自动装配。将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接 |
byType | 由属性数据类型自动装配。如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。 |
constructor | 类似于 byType,但该类型适用于构造函数参数类型。它尝试把它的构造函数的参数与配置文件中 beans 名称中的一个进行匹配和连线。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生。 |
autodetect | Spring首先尝试通过 constructor 使用自动装配来连接,如果它不执行,Spring 尝试通过 byType 来自动装配。 |
autowire=“byName”
Spring基于注解的配置
从 Spring 2.5 开始就可以使用注解来配置依赖注入
- @Required注释
应用于 bean 属性的 setter 方法 - @Autowired注释
应用到 bean 属性的 setter 方法,非 setter 方法,构造函数和属性。 - @Qualifier注释
通过指定确切的将被连线的 bean,@Autowired 和 @Qualifier 注解可以用来删除混乱。
@Autowired
@Qualifier("student1")
- JSR-250注释
Spring 支持 JSR-250 的基础的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。 - 基于Java的配置
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
上面的代码将等同于下面的 XML 配置:
<beans>
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld" />
</beans>
在这里,带有 @Bean 注解的方法名称作为 bean 的 ID,它创建并返回实际的 bean。
可以使用 AnnotationConfigApplicationContext 来加载并把他们提供给 Spring 容器:
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
- 事件处理
- 自定义事件