spring的地位
如图可以看出,sping纵跨整个项目架构,它是一个容器框架。下面使用一个简单的项目来认识spring。
快速入门
step
1、新建一个普通Java工程,spring只是一种容器,所以支持Java se和java ee
2、引入spring的开发包(最小配置spring.jar 该包把常用的jar都包括, 还要 写日志包 common-logging.jar
3、新建一个叫UserService类
package com.ydc.service;
public class UserService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("hello "+name );
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
4、创建spring的一个核心文件 applicationContext.xml, [hibernate有核心 hibernate.cfg.xml struts核心文件 struts-config.xml], 该文件一般放在src目录下,该文件中引入 xsd文件 :
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
5、配置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" xmlns:context="http://www.springframework.org/schema/context"
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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="userService" class="com.ydc.service.UserService">
<property name="name">
<value>杨德成</value>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
配置说明:
a、bean元素的作用是,当我们的spring框架加载时候,spring就会自动的创建一个bean对象,。
<bean id="userService" class="com.ydc.service.UserService">
- 1
- 1
执行这段代码会创建一个以下对象
UserService userSerivce=new UserService();
- 1
- 1
b、注入属性
<property name="name">
<value>杨德成</value>
</property>
- 1
- 2
- 3
- 1
- 2
- 3
执行完这个这段代码会给上面创建的对象属性赋值,体现了编程中常说的注入的概念。
userSerivce.setName("杨德成");
- 1
- 1
Bean的作用域
使用scope来配置
<bean id="userService" class="com.ydc.service.UserService" scope="singleton">
- 1
- 1
比如我配置了“singleton”
UserService u=(UserService)ac.getBean("userService");
UserService u2=(UserService)ac.getBean("userService");
- 1
- 2
- 1
- 2
u和u2就是同一个实例对象,如果换成”prototype”,那么u和u2就会是两个不同的实例对象,默认使用的是”singlton”,prototype性能开销比较大,慎用。
其它的可以去查api文档,这里不做一一介绍。
6、新建测试类TestMain
public class TestMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
//ApplicationContext ac=ApplicaionContextUtil.getApplicationContext();
UserService u=(UserService)ac.getBean("userService");
u.sayHello();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
a、通过配置文件applicationContext.xml实例化一个spring 的applicationContext对象(容器对象)。
b、解析XML文件,然后通过反射机制实例化bean,并且设置各个属性。
userService= Class.forName("com.service.UserService")
userService.setName("杨德成");
- 1
- 2
- 3
- 1
- 2
- 3
c、获得实例,可进行实例的一系列使用。
UserService u=(UserService)ac.getBean("userService");
u.sayHello();
- 1
- 2
- 1
- 2
通过上面的代码通过在配置文件中的id属性获得了对应的实例对象,我们并没有手动去new一个对象,这里又体现了编程中的另一个概念“ioc”
什么是ioc
ioc(inverse of controll ) 控制反转: 所谓控制反转就是把创建对象(bean),和维护对象(bean)的关系的权利从程序中转移到spring的容器(applicationContext.xml),而程序本身不再维护.
7、运行效果
下面把我的bean(这里指的是UserService类)复杂度提高
8、新建一个BybService类
package com.ydc.service;
public class BybService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayBye(){
System.out.println("bye"+name);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
9、在UserService引用或是依赖 BybService
10、修改核心配置文件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: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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="userService" class="com.ydc.service.UserService">
<property name="name">
<value>杨德成</value>
</property>
<property name="byeService" ref="bybService"></property>
</bean>
<bean id="bybService" class="com.ydc.service.BybService">
<property name="name">
<value>张三</value>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
a、同样把新的bean配置进入。
b、配置依赖关系
<property name="byeService" ref="bybService"></property>
- 1
- 1
11、再次运行测试:
到此已经把我们编程中一个重要的概念DI 已经体现出来。
什么是DI
di(dependency injection) 依赖注入: 实际上di和ioc是同一个概念,spring设计者认为di更准确表示spring核心技术
运行原理
继续推进
12、创建一个接口 ChangeLetter
package com.ydc.service;
public interface ChangeLetter {
//声明一个方法
public String change();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
13、创建一个大写字母转化类,并实现ChangeLetter接口
package com.ydc.service;
public class UpperLetter implements ChangeLetter {
private String str;
public String change() {
//把小写字母->大写
return str.toUpperCase();
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
14、创建一个小写字母转化类,并实现ChangeLetter接口
package com.ydc.service;
public class LowwerLetter implements ChangeLetter {
private String str;
public String change() {
// TODO Auto-generated method stub
return str.toLowerCase();
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
15、配置UpperLetter类
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="userService" class="com.ydc.service.UserService">
<property name="name">
<value>杨德成</value>
</property>
<property name="byeService" ref="bybService"></property>
</bean>
<bean id="bybService" class="com.ydc.service.BybService">
<property name="name">
<value>张三</value>
</property>
</bean>
<bean id="changeLette" class="com.ydc.service.UpperLetter">
<property name="str">
<value>yangdecheng</value>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
看到没有,这里并没有配置接口。
16、点击运行
通过代码可以看出,我们可以通过获取接口来调用配置文件中所配置的接口实现类的相应方法。
17、修改为配置另外一个实现类LowwerLetter
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="userService" class="com.ydc.service.UserService">
<property name="name">
<value>杨德成</value>
</property>
<property name="byeService" ref="bybService"></property>
</bean>
<bean id="bybService" class="com.ydc.service.BybService">
<property name="name">
<value>张三</value>
</property>
</bean>
<!-- <bean id="changeLette" class="com.ydc.service.UpperLetter"> <property
name="str"> <value>yangdecheng</value> </property> </bean> -->
<bean id="changeLette" class="com.ydc.service.LowwerLetter">
<property name="str">
<value>YDC</value>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
18、点击运行
spring可以使用接口编程配合di技术实现层与层的解耦。
bean的生命周期
快速了解
step
1、重新建立一个bean类
public class PersonService {
private String name;
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public PersonService(String abc){
System.out.println("PersonService 有参数构造函数");
}
public PersonService(){
System.out.println("PersonService 无参数构造函数");
}
public void setName(String name) {
System.out.println("setName(String name) 函数");
this.name = name;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
2、配置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" xmlns:context="http://www.springframework.org/schema/context"
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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="personService" class="com.ydc.beanlife.PersonService">
<!-- 这里注入我们属性,前提就是有setName才能ok -->
<property name="name">
<value>xiaoming</value>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
看见没,默认是会调起无参的构造函数,可以修改配置来调用有参构造函数。
3、测试运行
4、让bean(PersonService)实现BeanNameAware接口
@Override
public void setBeanName(String arg0) {
System.out.println("setBeanName 被调用 值"+arg0);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
看见没,该方法可以获取正在被实例化的bean 指定的id
5、让bean(PersonService)实现BeanFactoryAware接口
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
// TODO Auto-generated method stub
System.out.println("setBeanFactory "+arg0);
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
看见没,该方法可以传递beanFactroy
6、让bean(PersonService)实现ApplicationContextAware接口
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
// TODO Auto-generated method stub
System.out.println("setApplicationContext"+arg0);
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
看见没,该方法传递ApplicationContext
7、让bean(PersonService)实现InitializingBean接口
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("afterPropertiesSet()");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
看见没,该方法实在创建完bean之后被调用的。
8、让bean(PersonService)实现DisposableBean接口
@Override
public void destroy() throws Exception {
System.out.println("释放各种资源");
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
该方法在当前的bean被销毁时被调起。
可以不实现销毁接口,自己定制一个销毁的方法
@PreDestroy
public void mydestory() {
System.out.println("释放各种资源");
}
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
然后在配置一下定制的方法
<bean id="personService" destroy-method="mydestory" class="com.ydc.beanlife.PersonService" >
- 1
- 1
9、替代上面的InitializingBean接口
a、新建一个类似过滤器的后置处理器MyBeanPostProcessor类
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization 函数被调用");
System.out.println(arg0+" 被创建的时间是"+new java.util.Date());
return arg0;
}
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization 函数被调用");
return arg0;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
看见没,该类实现了BeanPostProcessor接口,见文生意,bean创建进度监控。
b、在配置文件中添加MyBeanPostProcessor
<bean id="myBeanPostProcessor" class="com.ydc.beanlife.MyBeanPostProcessor" />
- 1
- 1
c、测试