Spring框架图
目录结构
spring.jar
以及日志包common-logging.jar
)ApplicationContext.xml
, 该文件一般放在src目录下,该文件中引入xsd文件,可以自定义文件名。TestSpring
|---src
|---com.netease
| |---Service
| |---HelloService.java
| |---ByeService.java
| |---Test
| |---TestService.java
|---ApplicationContext.xml
External Libraries
|--- spring.jar
|--- common-logging.jar
|--- ...
代码详情
package com.netease.Service;
public class HelloService {
private String name;
private ByeService byeService; /** 引用了一个ByeService*/
public String getName() { return name;}
public void setName(String name) { this.name = name;}
public ByeService getByeService() { return byeService;}
public void setByeService(ByeService byeService) { this.byeService = byeService;}
public void sayHello() {
System.out.println("hello "+name);
}
}
package com.netease.Service;
public class ByeService {
private String name;
public String getName() { return name;}
public void setName(String name) {this.name = name;}
public void sayBye() {
System.out.println("Bye " + name);
}
}
package com.netease.Test;
import com.netease.Service.HelloService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestService {
public static void main(String[] args) {
/*通过反射机制,在Spring容器中生成对象*/
/*如果%%.xml放在某个包下,则就变为<包名+文件名>*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
HelloService helloService = (HelloService) applicationContext.getBean("helloService");
helloService.sayHello();
helloService.getByeService().sayBye();
}
}
Spring核心容器文件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">
<!--注意Spring如何配置Bean以及如何维护Bean之间的依赖-->
<bean id="helloService" class="com.netease.Service.HelloService">
<!--注入属性值-->
<property name="name">
<value>Today</value>
</property>
<!--维护Bean之间依赖,ref指向下一个Bean-->
<property name="byeService" ref="byeService"/>
</bean>
<bean id="byeService" class="com.netease.Service.ByeService">
<property name="name">
<value>Yesterday</value>
</property>
</bean>
</beans>
ApplicationContext ac = new ClassPathXmlApplicationContext("com/netease/bean.xml")
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/netease/bean.xml"))
factory.getBean("***")
获取某个bean时,才实例化该bean对应的对象。类似于延迟实例化
完整生命周期步骤如下(通常只用到加粗的几步):
ApplicationContext方式
Bean工厂方式
<beans>
<bean id="foo" class="...Foo"/>
<bean id="bar" class="...Bar"/>
</beans>
scope属性
<beans>
<bean id="foo" scope="prototype/singleton" class="...Foo"/>
<bean id="bar" class="...Bar"/>
</beans>
init-method 和destroy-method属性
init
和destroy
方法,函数名可自定义 <bean id="foo" init-method="init" destory-method="destroy" class="...Foo" >
@PostConstruct
public void ini(){…}
@PreDestroy
public void destroy(){…}
<bean id="foo" class="...Foo">
<property name="name">
<value>tom</value>
</property>
</bean>
<bean id="foo" class="...Foo">
<property name="name">
<ref bean="bar">
</property>
</bean>
<bean id="bar" class="...Bar">
</bean>
<bean id="foo" class="...Foo">
<property name="bar">
<bean class="...Bar">...</bean>
</property>
</bean>
<property name="barlist">
<null/>
</property>
<!-- 给数组注入值 -->
<property name="empName">
<list>
<value>小明</value>
<value>李雷</value>
<value>韩梅梅</value>
</list>
</property>
<!-- 给list注入值 list 中可以有相等的对象 -->
<property name="empList">
<list>
<ref bean="emp2" />
<ref bean="emp1"/>
<ref bean="emp1"/>
</list>
</property>
<!-- 给set注入值 set不能有相同的对象 -->
<property name="empsets">
<set>
<ref bean="emp1" />
<ref bean="emp2"/>
<ref bean="emp2"/>
</set>
</property>
<!-- 给map注入值只要key不同即可 -->
<property name="empMaps">
<map>
<entry key="11" value-ref="emp1" />
<entry key="22" value-ref="emp2"/>
<entry key="33" value-ref="emp1"/>
</map>
</property>
<property name="pp">
<props>
<prop key="pp1">abcd</prop>
<prop key="pp2">hello</prop>
</props>
</property>
public class Student
有name和age两个属性public class Gradate extends Student
有degree属性 <!-- 配置一个学生对象 -->
<bean id="student" class="com.hsp.inherit.Student">
<property name="name" value="顺平" />
<property name="age" value="30"/>
</bean>
<!-- 配置Grdate对象 -->
<bean id="grdate" parent="student" class="com.hsp.inherit.Gradate">
<!-- 如果自己配置属性name,age,则会替换从父对象继承的数据 -->
<property name="name" value="小明"/>
<property name="degree" value="学士"/>
</bean>
<bean id="test" class ="...Test">
<constructor-arg index="0" type="java.lang.String" value="朱洁" />
<constructor-arg index="1" type="int" value="20"/>
<constructor-arg index="2" type="double" value="34.5" />
</bean>
context:property-placeholder
引入属性文件,有多个需要使用','号间隔.
name=scott
drivername=oracle:jdbc:driver:OracleDirver
url=jdbc:oracle:thin:@127.0.0.1:1521:hsp
pwd=tiger
在ApplicationContext.xml文件中引入db.properties文件,两种方式
第一种
<context:property-placeholder location = "classpath:com/netease/db.properties,classpath:com/netease/db2.properties,..."/>
<bean id="dbPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>xx/yy/db.properties</value>
<value>xx/yy/db2.properties</value>
</list>
</property>
</bean>
<bean id="dbutil" class="com.hsp.dispatch.DBUtil">
<property name="name" value="${name}" />
<property name="drivername" value="${drivername}" />
<property name="url" value="${url}" />
<property name="pwd" value="${pwd}" />
</bean>
<bean id="foo" autowire="autowire type">
@ComponentScan
标签,则可以扫描该类所在包及其子包下面的所有带Component
注解的类,即所有组件;context:component-scan base-package="package-name"
自动装配方法
<context:annotation-config />
方可使用;@Scope("prototype")
@Repository
public class Demo { … }
使用 @PostConstruct 和 @PreDestroy 指定生命周期回调方法
使用 @Required 进行 Bean 的依赖检查
与XML的对应关系:对应于XML配置方式中的dependency-check
属性
属性 | 含义 --------|------------------ none | 默认不执行依赖检查 simple | 对原始基本类型和集合类型进行检查 objects | 对复杂类型进行检查 all | 对所有类型进行检查
使用 @Resource、@Autowired 和 @Qualifier 指定 Bean 的自动装配策略
@Autowired(required=false)
@Qualifier("ppp")
public void setPerson(person p){}
@Autowired(required=false)
public void sayHello(@Qualifier("ppp")Person p,String name){}
<bean id="person" class="footmark.spring.Person">
<qualifier value="ppp"/>
</bean>
@Configuration
public class BookStoreDaoConfig{
@Bean
public UserDao userDao(){ return new UserDaoImpl();}
@Bean
public BookDao bookDao(){return new BookDaoImpl();}
}
Spring 在解析到以上文件时,将识别出标注 @Bean 的所有方法,执行之,并将方法的返回值 ( 这里是 UserDaoImpl 和 BookDaoImpl 对象 ) 注册到 IoC 容器中。默认情况下,Bean 的名字即为方法名。因此,与以上配置等价的 XML 配置如下:<bean id=”userDao” class=”bookstore.dao.UserDaoImpl”/>
<bean id=”bookDao” class=”bookstore.dao.BookDaoImpl”/>
// 假设存在如下的 @Configuration 类:
package bookstore.config;
import bookstore.dao.*;
@Configuration
public class MyConfig{
@Bean
public UserDao userDao(){
return new UserDaoImpl();
}
}
//此时,只需在 XML 中作如下声明即可:
<beans … >
……
<context:annotation-config />
<bean class=”demo.config.MyConfig”/>
</beans>
<context:component-scan base-package=”bookstore.config” />
@Configuration
@ImportResource(“classpath:/bookstore/config/spring-beans.xml”)
public class MyConfig{
}
// 容器的初始化过程和纯粹的以配置为中心的方式一致:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
相关阅读:Spring学习记录 (下篇)
本文来自网易实践者社区,经作者朱洁授权发布。