作为工作一段时间的程序猿,一直没有对Spring和SpringMVC进行过系统的学习,却经常使用,对于原理并不理解,今天先记录下Spring中的一些使用,待后续系统学习时补充。
一、IOC和DI
SpringIOC即控制反转,思想是反转资源获取的方向,由容器主动将资源推送给它所管理的组件,而不需要组件向容器发起请求查找后由容器返回资源。
DI即依赖注入,是IOC的另一种表述,组件以一些预定义好的方式接收来自容器的依赖注入,这些方式可为setter方法注入、构造器注入。
二、Bean的配置
Spring中配置Bean的方式主要由两种:xml文件的形式和注解的形式。
(一)、基于xml的形式配置Bean.
基于xml的形式配置bean大致分为三种:通过全类名(反射)的方式、通过工厂方法(静态工厂方法和实例工厂方法)、通过factoryBean的形式。在实例化Bean的过程中,可通过setter方法注入、构造器注入为Bean的属性赋值。
1、通过反射机制配置Bean
<!--
配置Bean:
class:bean的全类名,通过反射的方式创建Bean,所以要求Bean中存在一个无参的构造函数
id:唯一标识
依赖注入:
通过setter方法注入,配置bean的属性
-->
<bean id="helloWorld" class="com.github.wangxin.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<!--
通过构造器注入,配置bean的属性,可以指定参数位置和类型,以区分重载的构造器
-->
<bean id="car" class="com.github.wangxin.beans.Car">
<constructor-arg index="0" value="BMW"/>
<constructor-arg index="1" value="Shanghai"/>
<constructor-arg index="2" value="50000"/>
</bean>
<bean id="car2" class="com.github.wangxin.beans.Car">
<constructor-arg type="java.lang.String" value="BMW"/>
<constructor-arg type="java.lang.String" value="Shanghai"/>
<constructor-arg type="int" value="50"/>
</bean>
<bean id="person" class="com.github.wangxin.beans.Person">
<property name="name" value="WangXin"></property>
<property name="age" value="25"></property>
<!-- 可以使用ref 属性建立 bean之间的关系 -->
<property name="car" ref="car"></property>
</bean>
<bean id="person2" class="com.github.wangxin.beans.Person">
<property name="name" value="WangXin"></property>
<property name="age" value="25"></property>
<!-- 也可以使用内部Bean的形式,内部Bean只能在内部使用,无法在别处使用 -->
<property name="car" >
<bean class="com.github.wangxin.beans.Car">
<constructor-arg type="java.lang.String" value="BMW"/>
<constructor-arg type="java.lang.String" value="Shanghai"/>
<constructor-arg type="int" value="50"/>
</bean>
</property>
</bean>
2、通过工厂方法配置
<!--
通过静态工厂方法配置Bean
factory-method:静态工厂方法
constructor-arg:使用constructor-arg为静态工厂方法传入参数
-->
<bean id="person" class="com.github.wangxin.factory.StaticFactory" factory-method="getPerson">
<constructor-arg name="name" value="wx"></constructor-arg>
</bean>
<!-- 实例化工厂方法实例 -->
<bean id="instancePersonFactory" class="com.github.wangxin.factory.InstancePersonFactory"></bean>
<!--
通过实例化工厂方法配置Bean
factory-bean:指向实例工厂方法的bean
factory-method:工厂方法
constructor-arg:使用constructor-arg为静态工厂方法传入参数
-->
<bean id="person1" factory-bean="instancePersonFactory" factory-method="getPerson">
<constructor-arg name="name" value="wx"></constructor-arg>
</bean>
3、通过factoryBean方式配置,需要自己实现Spring的factoryBean接口
<bean id="person" class="com.github.wangxin.factorybean.PersonFactoryBean">
<property name="name" value="WX"/>
</bean>
public class PersonFactoryBean implements FactoryBean {
private String name;
public void setName(String name) {
this.name = name;
}
//获取对象实例
@Override
public Object getObject() throws Exception {
return new Person(name,12);
}
//返回对象类型
@Override
public Class<?> getObjectType() {
return Person.class;
}
//是否单例
@Override
public boolean isSingleton() {
return true;
}
}
Bean的生命周期
<!--
spring管理bean的生命周期,bean包含如下五个生命周期:
1、使用构造器创建实例
2、调用set方法进行赋值
3、如果指定初始化方法,调用初始话方法
4、使用Bean
5、在容器关闭时,调用bean的销毁方法
-->
<bean id="person" class="com.github.wangxin.cycle.Person" init-method="init" destroy-method="destroy">
<property name="name" value="wang xin"></property>
</bean>
<!--
bean的后置配置器,用于bean在初始化方法前后进行处理,
postProcessBeforeInitialization:在初始化方法init-method前进行处理
postProcessAfterInitialization:在初始化方法init-method后进行处理,可在其中对bean实现偷梁换柱
-->
<bean class="com.github.wangxin.cycle.MyBeanPostProcessor" />
Bean的作用域
<!--
使用scope属性配置bean的作用域
singleton:默认作用域,容器初始化时创建bean,整个生命周期内只有一个,单例模式
prototype:多实例的,容器初始化时不创建bean,而是每次请求时都创建一个实例
request:发出http请求时才创建对象,每次发起都会创建
session:发出session时创建对象,每次发起时都会创建
global session:一盘用于Portlet环境
-->
<bean id="helloWorld" class="com.github.wangxin.scope.HelloWorld" scope="singleton"></bean>
<bean id="helloWorld2" class="com.github.wangxin.scope.HelloWorld" scope="prototype"></bean>
(二)、基于注解的形式配置Bean.
基于注解的形式配置Bean,需要在xml文件中配置<context:component-scan base-package="****"/> 标签,指定ioc容器扫描的包。主要有四个标签:
@Component:Spring的一个基本注解,标识了一个受Spring管理的组件
@Service:标识服务层组件
@Controller:标识控制层组件
@Repository:标识持久层组件
@Autowired :默认注入单例的bean。如果发现找到有很多bean,可以加上@Qualifier("XXX")配置使用。若非必须装配则可以设置required=false。
<!--指定ioc容器扫描的包 -->
<context:component-scan base-package="com.github.wangxin.annotation"> </context:component-scan>
<!--指定ioc容器扫描的包.通过resource-pattern指定扫描的资源 -->
<context:component-scan base-package="com.github.wangxin.annotation"
resource-pattern="repository/*.class"> </context:component-scan>
<!--指定ioc容器扫描的包.通过exclude-filter子节点指定排除哪些组件 -->
<context:component-scan base-package="com.github.wangxin.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
<!--指定ioc容器扫描的包.通过exclude-filter子节点指定只包含哪些组件,需要配合use-default-filters="false"使用,该属性默认为true -->
<context:component-scan base-package="com.github.wangxin.annotation" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>