一、概述
spring是分层的javaSE/EE应用一站式的轻量级开源框架,以IoC和AOP为内核,提供了展现层SpringMVC,持久层Spring JDBC以及业务层事务管理等一站式的企业级应用技术。
二、IoC容器主题
spring框架主要是利用java反射的原理,通过加载配置文件完成类的创建,从而达到控制反转的目的。
在web.xml 中配置spring 监听器,web容器启动时,就会默认执行它实现的方法,自动装配Spring applicationContext.xml 的配置信息。(applicationContext.xml中描述了bean的信息以及bean中的依赖关系,还有其他的配置信息)。
- 配置监听器.
- BeanFactory和ApplicationContext.
2.1 BeanFactory是spring框架的底层接口,提供了高级IoC的配置机制。
2.2 ApplicationContext上下文容器是由BeanFactory派生而来的,可以通过配置的方式来实现很多BeanFactory编程式实现的功能。使用方式如下(bean配置见后)。
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService) ac.getBean("userService");
us.sayHello();
而在web开发中,spring专门设置了WebApplicationContext,它允许从相对web根目录的路径中装载配置文件完成初始化工作。从它中可以获得ServletContext的引用,整个web应用上下文对象将作为属性放置到ServletContext中,以便web应用环境可以访问Spring应用上下文。
ServletContext servletContext = ServletActionContext.getServletContext();
// 需要使用WEB的工厂的方式
WebApplicationContext context =WebApplicationContextUtils.getWebApplicationContext(servletContext);
CustomerService cs = (CustomerService) context.getBean("customerService");
3.Bean的生命周期
Spring中定义Bean的生命周期,一从bean的作用范围,二从实例化bean经历的过程。
3.1 以BeanFactory中的Bean为讨论例子
(1)bean实例化(通过构造方法或者工厂方法)(必须)
(2)装配,属性赋值(可选的)
(3)回调(容器-控制类和组件-回调类)各种接口的实现配置(可选的)
(4)初始化(init-method=" ")
(5)就绪
(6)销毁(destroy-method=" ")
3.2 ApplicationContext中的bean和1)类似,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization()。
正因为Bean的生命周期不但和器实现的接口有关,还和bean的作用域有关,为了让Bean绑定在spring框架上,我们经常使用配置方式而非接口方式进行bean生命周期的控制。
4.在IoC容器中装配Bean
4.1配置概述
(1)Bean配置信息首先定义了Bean的实现以及依赖关系
(2)Spring容器根据各种形式的Bean配置信息在容器内部建立Bean注册表
(3)Spring容器根据注册表加载、实例化Bean,并建立Bean之间的依赖关系
(4) 最后Spring容器把这些准备就绪的bean放到Bean缓存池里中,以供外层的应用程序进行调用。
4.2基于xml的配置
(1)文件信息如下:
(2)bean配置如下
1)普通注入,直接<bean id=" 唯一指定名" class="指代要注入的类的名称,一般指:包名.类名">
2)依赖注入(bean中的变量赋值以及bean之间的依赖关系)
a.属性注入
一要在类中定义属性变量名,但是不要去new;二要提供对应的setter方法。
b.构造方法注入
c.工厂方法注入(已经融入底层)
<?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="userService" class="com.pan.demo1.UserServiceImp"></bean>
<bean id="customerDao" class="com.pan.demo1.CustomerDaoImpl"></bean>
<!-- setter方法注入 -->
<bean id="customerService" class="com.pan.demo1.CustomerServiceImpl">
<property name="customerDao" ref="customerDao"></property>
</bean>
<!-- 构造函数方式注入 -->
<bean id="car1" class="com.pan.demo1.Car1">
<constructor-arg name="cname" value="奇瑞"></constructor-arg>
<constructor-arg name="price" value="12344"></constructor-arg>
</bean>
<!--setter方法注入Car1-->
<property name="cname"><value>奇瑞</value></property>
<property name="price"><value>12344</value></property>
</beans>
3)注入参数详解
a.引用其他Bean,如上面的customerService和customerDao
b.内部bean,对象只是被当前对象使用,不提供给其他对象使用。
<bean id="boss" class="com.pan.Boss">
<property name="car">
<bean class="com.pan.Car1">
<property name="cname"><value>奇瑞</value></property>
<property name="price"><value>12344</value></property>
</bean>
</property>
</bean>
c.null值
<property name="price"><null/></property>
d.级联属性(此时必须在boss类中对car属性声明一个初始化对象)
<bean id="boss" class="com.pan.Boss">
<property name="car.cname">吉利</property>
</bean>
e.集合类型属性
①list(在boss类中声明list集合并初始化)(set用<set>)
<bean id="boss" class="com.pan.Boss">
<property name="favorties">
<list>
<value>看报</value>
<value>赛车</value>
<value>高尔夫</value>
</list>
</property>
</bean>
②Map(在boss类中声明Map并初始化)
<property>
<map>
<entry>
<key><value>AM</value></key>
<value>会见客户</value>
<entry>
<map>
</property>
4)<bean>之间的关系
①继承(和java类概念相同)
<bean id="boss" class="com.pan.Boss" abstract="true"/>
<bean id="car2" parent="boss"/>
<bean id="car3" parent="boss"/>
②依赖<ref>
③引用<idref>
(5)Bean的作用域
① singleton(单例模式):在spring Ioc容器中仅存在一个bean实例。Spring环境中,对Dao类都采用单例模式,因为spring利用 AOP和LocalThread 功能,对非线性安全的变量进行了特殊处理,使其变得安全。(soring默认单例),如果不希望提前实例化,可以通过设置lay-init属性控制;
② prototype(多例模式): 每次从容器中调用bean时,都返回一个新的实例,如action类;
③ request:对应一个HTTP请求的生命周期;
④ session: 横跨整个httpSession,只有当HttpSession结束了才会它被销毁;
⑤glabalSession:类似于session,仅在Portlet环境中有用。
4.3 Bean注解式配置
采用注解式的配置文件,则Bean定义的信息通过在bean实现类上标注注解实现的。
1)@Compent注解
①@Repository-----Dao类
②@Service---------Service类
③@Controller------Controller类
/*
<bean id="userService" class="com.pan.UserServiceImp">
*/
@Component(value="userService")
public class UserServiceImp implements UserService{
@Value(value="美美")
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void sayHello() {
System.out.println("hello spring !!!"+name);
}
}
为了能顺利使用注解,必须在ApplicationContext.xml配置自动扫描注解。
<context:component-scan base-pase-package="存放类的包名">
2)自动注入(@Autowired,@Qualifier)
@Service
public class LogonService{
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
@Autowired默认按类型匹配的方式在容器中查找匹配的bean,当有且仅当有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。当容器中有俩个类型为UserDao的Bean,通过@Qualifier可以指定注入名为userDao的Bean.
参考书籍《精通Spring 4.x 企业应用开发实战》