Spring(一)-IOC
2017-07-19 本文已影响0人
yzw12138
一、Spring定义
Spring是一个开源框架,为简化企业级开发应用而生,使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能,它是一个IOC(DI)(依赖注入)和AOP(面向切面编程)容器框架。
- 一站式:在IOC和AOP基础上可以整合各种企业应用的开源框架和第三方类库。
二、环境搭建
- 1、新建工程
- 2、导入五个必备jar包
commons-logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
三、Spring具体应用
1、IOC&DI
Paste_Image.png- IOC前生
1) 分离接口与实现
2)工厂设计模式
Paste_Image.png3)反转控制
Paste_Image.png2、IOC中Bean的配置
- 1、基于xml文件
创建HelloWorld类,包含一个name对象和一个hello()方法。
创建SpringBean配置文件,命名为applicationContext.xnl,并配置内容。
<!--
id:标识容器中的bean,id唯一
class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求bean中必须带有无参的构造器
-->
<bean id="helloWorld" class="com.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
//创建Spring的IOC容器对象
//ApplicationContext 代表IOC容器
//ClassPathXmlApplicationContext:ApplicationContext 接口的实现类,该实现类从类路径下加载配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("appllicationContext.xml");
//从IOC容器中获取Bean实例
//利用id定位IOC容器中的bean,还可以同类型HelloWorld.class来获得,此时IOC容器中bean必须只有一个
HelloWorld helloWorld=(HelloWorld)ctx.getBean("helloWorld");
//调用类中方法
helloWorld.hello();
Paste_Image.png
Paste_Image.png
-
2、配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法&实例工厂方法)、FactoryBean
-
3、IOC的依赖注入
1)属性注入
<bean id="helloWorld" class="com.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
2)构造器注入
<bean id="car" class="com.bean.Car">
<constructor-arg value="Audi"></constructor-arg>
<constructor-arg value="ShangHai"></constructor-arg>
</bean>
当存在重载构造器时,可以再constructor-arg中添加位置(index)或者类型(type)来进行区分
外部bean的引入:
<bean id="person" class="com.bean.Person">
<property name="name" value="Tom"></property>
<property name="age" value="24"></property>
<property name="car" reg="car"></property>
</bean>
Paste_Image.png
Paste_Image.png
3)工厂方法注入(很少使用,不推荐)
注意:
- a、内部bean不能被外部引用,只能在内部使用。
- b、级联属性:bean支持为级联属性赋值,但必须初始化后才能进行赋值。和struts2不同
- c、集合属性:
<bean id="person2" class="com.bean.Person">
<property name="name" value="Mike"></property>
<property name="age" value="23"></property>
<property name="cars" >
<list>
<ref bean="car"/>
<ref bean="car1"/>
<ref bean="car2"/>
</list>
</property>
</bean>
Paste_Image.png
Paste_Image.png
<!--配置properties属性,如连接数据库-->
<bean id="dataSource" class="class.bean.DataSource>
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">123456</prop>
<prop key="jdbcUrl">jdbc:mysql:///test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
配置独立的集合bean,当多个bean都需要用到这个集合时,可以直接进行引用,需要导入util命名空间:
<uti-list>
<ref bean="car"/>
<ref bean="car2"/>
</uti-list>
- 通过p命名空间未bean赋值,需要先导入p命名空间
<bean id="person3" class="com.bean.person" p:name="Jack" p:age="34" p:car-ref="cars" ></bean>
- 4、自动装配
<bean id="car" class="com.bean.Car" p:brand="Aodi" p:price="30000"></bean>
<bean id="adress" class="com.bean.Ardress" p:city="BeiJing" p:street="HongQi"></bean>
<!--byName自动装配是根据bean的名字和当前bean的setter方法的属性名进行自动装配,当bean的id变成car1是就无法装配car;
byType根据bean的类型和当前bean属性的类型进行自动装配,若此时IOC容器中有两个以上的类型匹配bean,则会抛出异常。
-->
<bean id="person" class="com.bean.Person" p:name="Tom" autowire="byName"></bean>
- 5、自动装配的缺点
- 6、bean的继承
<bean id="adress" class="com.bean.Adress" p:city="BeiJing" p:street="Dazhogn"></bean>
<bean id="adress2" parent="adress" p:street="Dazhogn"></bean>
Paste_Image.png
当某一个bean没有指定的class属性时,他必须是一个抽象bean,否则会报错。
- 7、bean的作用域
<!--
使用bean的scope属性来配置bean的作用域
singleton:默认值。容器初始时创建bean实例,在整个容器的生命周期中只创建这一个bean,单例的。
prototype:原型的。容器初始化时不创建bean实例,在每次请求时都创建一个新的bean,并返回。
-->
<bean id="car" class="com.bean.Car">
<constructor-arg value="Audi"></constructor-arg>
<constructor-arg value="ShangHai"></constructor-arg>
</bean>
- 8、bean外部属性文件
原因:在配置文件里 配置bean时,有时需要在bean的配置里混入系统部署的细节信息(例如:文件路径,数据源配置信息等)。而这些部署细节实际上需要和bean的配置分离。
已导入数据源为例:
首先导入c3p0-0.9.1.2.jar包和mysql驱动包
新建一个文件db.properties,写入要进行导入的属性
user=root
password=123456
jdbcUrl=jdbc:mysql:///test
driverClass=com.mysql.jdbc.Driver
<!--导入属性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="class.bean.DataSource>
<property name="properties">
<props>
<prop key="user" value=${user}></prop>
<prop key="password" value=${password}></prop>
<prop key="jdbcUrl" value=${jdbcUrl}></prop>
<prop key="driverClass" value=${driverClass}></prop>
</props>
</property>
</bean>
- 9、Spring表达式语言SpEL:
<bean id="car" class="com.bean.Car">
<property name="brand" value="Audi"></property>
<property name="price" value="300000"></property>
<!--tyrePerimeter表示轮胎周长,使用SpEL引用类的静态属性-->
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI*80}></property>
</bean>
<bean id="preson" class="com.bean.Person">
<!--使用SpEl引用其他bean-->
<property name="car" value="#{car}"></property>
<!--使用SpEL引用其他bean的属性-->
<property name="city" value="#{adress.city}"></property>
<!--使用SpEL的运算符-->
<property name="info" value="#{car.price>300000 ? '金领':'白领'}></property>
</bean>
- 10、bean的生命周期(视频10)
public class Car(){
public Car(){
System.out.println("Car Constructor.....");
}
private String brand;
public void setBrand(){
System.out.println("serBrand...");
this.brand=brand;
}
public void init(){
System.out,println("init...");
}
public xoid destory(){
System.out.println("destory...");
}
}
<bean id="car" class="com.bean.Car"
init-method="init"
destory-method="destory">
<property name="brand" value="Audi"></property>
</bean>
<!--
实现BeanPostProcessor接口,并具体提供
Object postProcessBeforeInitialization(Object bean,String beanName):init-method之前调用
Object postProcessAfterInitialization(Object bean,String beanName):init-method之后调用
的实现
bean:bean实例本身
beanName:IOC容器中配置的bean的名字
返回值:实际返回给用户的bean,可以通过以上两个方法修改返回的bean,甚至返回一个新的bean
-->
<bean class="com.bean.MyBeanPostProcessor"></bean>