一、spring环境搭建
1、 所需jar包:
aspectjrt.jar
aspectjweaver.jar
cglib-nodep-2.1_3.jar
commons-logging.jar
spring.jar
2、 配置文件:
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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 引入的子配置文件 -->
<import resource="子配置文件路径"/>
</beans>
********************************************************************************
二、 入门案例
1、类
------------------------------------------------------------------------------------
public class HelloWorld {
public void hello(){
System.out.println("hello world~");
}
}
------------------------------------------------------------------------------------
2、配置文件
------------------------------------------------------------------------------------
<!-- beans: 把一个类放入到spring容器中,该类就是一个bean -->
<!-- id: 唯一标识符 class: 类的全名 -->
<bean id="helloWorld" class="cn.itcast.ioc.createObject.HelloWorld"></bean>
<!-- 也可以为该bean设置别名 name的属性和bean的id对应 -->
<alias name="helloWorld" alias="别名例子"/>
------------------------------------------------------------------------------------
3、测试类
------------------------------------------------------------------------------------
public class CreateObjectTest {
@Test
public void testCreateObject(){
// 1. 启动spring容器 注: applicationContext.xml在src下
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 从spring容器中把对象取出来,也可以使用别名来获取
//HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
HelloWorld helloWorld = (HelloWorld) context.getBean("别名例子");
// 3. 对象调用方法
helloWorld.hello();
}
}
------------------------------------------------------------------------------------
三、 控制反转
1、 作用: 把对象的创建、初始化、销毁等工作交给spring容器来做,由spring容器控制对象的生命周期。
2、 spring配置文件中,只要是一个bean就会为该bean创建对象
3、 spring容器创建对象的方式
方式一: 默认是调用默认的构造函数
例:
*****************************************************************************
类:
public class HelloWorld {
public HelloWorld(){
System.out.println("spring默认构造函数创建对象");
}
public void hello(){
System.out.println("hello world");
}
}
配置文件:
<!-- 利用默认的构造函数创建bean对象 -->
<bean id="helloWorld_C_M" class="cn.itcast.ioc.createObject.method.HelloWorld"></bean>
测试:
@Test
public void testCreateMethdo_DefaultConstructor(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld_C_M");
helloWorld.hello();
}
*****************************************************************************
方式二: 利用静态工厂方法创建
spring调用工厂方法产生对象,但是真正创建对象还是由程序员来完成的
例:
*****************************************************************************
类:
public class HelloWorldFactory {
public static HelloWorld getInstance(){
return new HelloWorld();
}
}
配置文件:
<!-- 利用静工厂模式创建bean对象 factory-method工厂方法: 工厂类中指定的方法 -->
<bean id="helloFactory" class="cn.itcast.ioc.createObject.method.HelloWorldFactory"
factory-method="getInstance"></bean>
测试:
@Test
public void testCreateMethdo_Factory(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("helloFactory");
helloWorld.hello();
}
*****************************************************************************
方式三: 实例工厂方法
注: 了解即可,配置文件中为:
<bean id="" factory-bean="" factory-method="" />
4、 spring容器创建对象的时机
注: 验证是否为单例,只需获取俩次bean对象,判断其hashcode是否相同即可
1.在单例的情况下(默认为单例)
1、在默认的情况下,启动spring容器创建对象
2、在spring的配置文件bean中有一个属性lazy-init="default/true/false"
1、如果lazy-init为"default/false"在启动spring容器时创建对象
2、如果lazy-init为"true",在context.getBean时才要创建对象
意义:
在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,
如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了
内存中,如果有数据,则对内存来是一个消耗
在第二种情况下,可以减少内存的消耗,但是不容易发现错误
2.在多例的情况下
就是一种情况:在context.getBean时才创建对象
5、 spring的bean中的scope
1、由spring产生的bean默认是单例的
2、可以在spring的配置文件中,scope的值进行修改="singleton/prototype/request/session/global session"
3、如果spring的配置文件的scope为"prototype",则在得到该bean时才创建对象
6、 spring容器对象的生命周期
1、spring容器创建对象
2、执行init方法
3、调用自己的方法
4、当spring容器关闭的时候执行destroy方法
注:当scope为"prototype"时,spring容器就不再调用destroy方法
例:
--------------------------------------------------------------------------
类:
public class HelloWorld {
public HelloWorld(){
System.out.println("被创建");
}
public void init(){
System.out.println("init");
}
public void hello(){
System.out.println("hello world~");
}
public void destroy(){
System.out.println("destroy");
}
}
配置文件:
<bean id="helloInitDestroy" class="cn.itcast.ioc.initDestory.HelloWorld"
init-method="init" destroy-method="destroy" scope="prototype"></bean>
测试:
@Test
public void testInitDestroy(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("helloInitDestroy");
helloWorld.hello();
// 注: 必须转换为ClassPathXmlApplicationContext,才可以调用close方法
ClassPathXmlApplicationContext applicationContext = (ClassPathXmlApplicationContext) context;
applicationContext.close();
}
--------------------------------------------------------------------------
四、 spring的DI: 依赖注入
1、 作用: 给属性赋值
2、 方式一: 利用set方式给属性赋值
一个类中的属性都可以采用springDI的方式进行赋值,但是并不是所有的属性都适合赋值
property是用来描述一个类的属性
基本类型的封装类、String等需要值的类型用value赋值;引用类型用ref赋值
例子:
---------------------------------------------------------------------------------------
类:
public class Person {
private Long pid;
private String pname;
private Student student;
private Set sets;
private List lists;
private Map map;
private Properties properties;
// set/get属性
}
public class Student {}
配置文件:
<bean id="student_set" class="cn.itcast.di.set.Student"></bean>
<bean id="person_set" class="cn.itcast.di.set.Person">
<property name="pid" value="1"></property>
<property name="pname" value="aaa"></property>
<property name="student">
<ref bean="student_set"/>
</property>
<property name="lists">
<list>
<value>list1</value>
<ref bean="student_set"/>
<value>list2</value>
</list>
</property>
<property name="sets">
<set>
<value>set1</value>
<ref bean="student_set"/>
<value>set2</value>
</set>
</property>
<property name="map">
<map>
<entry key="m1">
<value>map1</value>
</entry>
<entry key="m2">
<ref bean="student_set"/>
</entry>
</map>
</property>
<property name="properties">
<props>
<prop key="prop1">
prop1
</prop>
<prop key="prop2">
prop2
</prop>
</props>
</property>
</bean>
---------------------------------------------------------------------------------------
方式2: 利用构造函数给属性赋值
1、如果spring的配置文件中的bean中没有<constructor-arg>该元素,则调用默认的构造函数
2、如果spring的配置文件中的bean中有<constructor-arg>该元素,则该元素确定唯一的构造函数
index 代表参数的位置 从0开始计算
type 指的是参数的类型
value 给基本类型赋值
ref 给引用类型赋值
例子:
---------------------------------------------------------------------------------------
类:
public class Person {
private Long pid;
private String pname;
private Student student;
private Set sets;
private List lists;
private Map map;
private Properties properties;
public Person(){}
public Person(String pname, Student student) {
super();
this.pname = pname;
this.student = student;
}
}
public class Student {
public void aaa(){
System.out.println("student");
}
}
配置文件:
<bean id="student_con" class="cn.itcast.di.constructor.Student"></bean>
<bean id="person_con" class="cn.itcast.di.constructor.Person">
<constructor-arg index="0" type="java.lang.String" value="aaa"></constructor-arg>
<constructor-arg index="1" type="cn.itcast.di.constructor.Student" ref="student_con"></constructor-arg>
</bean>
测试:
@Test
public void testDIConstructor(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) context.getBean("person_con");
System.out.println(person.getPname());
person.getStudent().aaa();
}
---------------------------------------------------------------------------------------
3、 springIOC和DI的意义:
实现了完全的面向接口编程,即等号俩边都是借口,可以在配置文件中更改接口的实现方式。
4、 利用springIOC和DI实现MVC模式(set方式为例)
例:
---------------------------------------------------------------------------------------
Action层:
public class PersonAction {
private PersonService personService;
public PersonService getPersonService() {
return personService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public void savePerson(){
this.personService.savePerson();
}
}
Service层:
public interface PersonService {
public void savePerson();
}
ServiceImpl层:
public class PersonServiceImpl implements PersonService {
private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
public void savePerson() {
this.personDao.savePerson();
}
}
Dao层:
public interface PersonDao {
public void savePerson();
}
DaoImpl层:
public class PersonDaoImpl implements PersonDao {
public void savePerson() {
System.out.println("操作数据库的代码");
}
}
配置文件:
<bean id="personDao" class="cn.itcast.spring.mvc.test.PersonDaoImpl"></bean>
<bean id="personService" class="cn.itcast.spring.mvc.test.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>
<bean id="personAction" class="cn.itcast.spring.mvc.test.PersonAction">
<property name="personService">
<ref bean="personService"/>
</property>
</bean>
测试:
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDao");
personDao.savePerson();
}
---------------------------------------------------------------------------------------