Spring -- 入门,装备集合,自动装配,分散装配,自定义编辑器
1. 概要
struts2:web
hibernate:持久化
spring:业务层.管理bean的,容器.List Map Set. 体验spring:
1.创建java项目.
2.引入spring的类库.
${spring解压目录}/dist/spring.jar
${spring解压目录}/lib/jakarta-commons/commons-logging.jar
2'.创建业务类.
/**
* GreetingService
*/
public class GreetingService {
private String greeting ;//get/set
private String greeting2 ;//get/set /* byeService */
private ByeService bs ;//get/set
public void sayGreeting(){
bs.sayBye();
}
} /**
* ByeService
*/
public class ByeService {
private String bye ; public String getBye() {
return bye;
} public void setBye(String bye) {
this.bye = bye;
} public void sayBye(){
System.out.println(bye);
}
}
3.配置spring的配置文件.src/applicationContext.xml
schema:${spring解压目录}\docs\reference\html_single\index.html\3.2.1.1
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 欢迎服务 -->
<bean id="greetingService" class="cn.itcast.spring.service.GreetingService">
<property name="greeting">
<value>hello world</value>
</property>
<property name="greeting2" value="tom" />
<property name="bs" ref="byeService" />
</bean>
<!-- 欢送服务 -->
<bean id="byeService" class="cn.itcast.spring.service.ByeService">
<property name="bye">
<value>later</value>
</property>
</bean>
</beans>
4.创建app.
ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
GreetingService gs = (GreetingService) ac.getBean("greetingService");
gs.sayGreeting();
gs.sayGreeting2(); ByeService bs = (ByeService) ac.getBean("byeService");
bs.sayBye(); spring:
ioc: inverse of control,反转控制.获得依赖对象的方式被反转了. (不要手动new bean对象)
1.new.(spring负责对象实例化)
2.组装对象的出发点是反的(相对于bean的依赖关系是反的).
DI:dependency injection,依赖注入. <==> ioc
aop: aspect oriented program,面向方面编程. oop:面向对象编程. soa: GreetingService gs = new ...(); gs.setByeService(bs); ByeService bs = new ...();
gs.sayGreeting(); BeanFactory:实例化bf时,不会实例化任何bean,只有getBean的时候,才实例化相关的bean.节省资源.
ApplicationContext:实例化ac时,实例化单例bean.
懒汉式:
public class A{
private A(){} public static A instance = null ;
public static A getInstance(){
if(instance == null){
instance = new A();
}
return instance ;
}
} 饿汉式:
public static A instance = new A(); spring单利bean,对应的bean的叫做prototype(原型bean). ac.getBean("bs"); == new ByeService(); 生命周期:
1.new
2.set DI
3.BeanNameAware:bean名关注
4.BeanFactoryAware:bean工厂关注
5.BeanPostProcessor.beforeInitialization();
5'.调用InitializingBean.afterPropertySet()方法.
6.init-method
7.BeanPostProcessor.afterInitialization(); spring()框架. 代码的入侵.
1.高侵入性
2.低侵入
3.非侵入行 jee:jsp servlet jpa jta ejb(enterprise javabean),jndi
pojo:plain old java object. BeanDefinition:bean的定义,spring对bean的信息的封装.
Root bean: class [cn.itcast.spring.service.GreetingService]; scope=singleton; abstract=false; lazyInit=false;
autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null;
factoryMethodName=null; initMethodName=ini; destroyMethodName=release; defined in class path resource
[applicationContext.xml] Class clazz = Class.forName("cn.itcast.spring.service.GreetingService");
clazz.newInstance(); scope:prototype singleton request session global_session <struts>
<package namepace extends=""> 在ide下注册spring中的schema文件.
${spring解压目录}\dist\resources\*.xsd. List Set Map:
Properies:
.properties <hibernate-mapping>
<class name table lazy>
<id >
<generator class="" />
</id>
<property name="age" column access="field">
</class> spring通过构造函数参数注入依赖强化依赖关系. 自动装配:
1.byName:按照名称自动装配,寻找和bean的属性名相一致的bean的id.(bean必须有空的构造,通过set方法注入)
2.byType:按照属性的类型来自动装配,如果找到多个,抛异常.(bean必须有空的构造,通过set方法注入)
3.constructor:按照构造函数参数的类型自动装配,如果找不到或者找多个,都抛异常.
4.autodetact:自动检测,在(2)和(3)之间选择一个 5.no.
6.default,跟<beans default-autowire属性>保持一致. 分散配置:
把需要在上下文硬编码的属性拿到外部的属性文件中定义,让上下文从外部文件提取值. 自定义编辑器:
将字符串转换成相应的对象,
2. Spring中bean的生命周期, 及其工作流程
bean被载入到容器中时,他的生命周期就开始了。bean工厂在一个bean可以使用前完成很多工作:
1).容器寻找bean的定义信息并实例化。
2).使用依赖注入,spring按bean定义信息配置bean的所有属性。
3).若bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递bean的ID。
4).若bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
5).若BeanPostProcessor和bean关联,则它们的postProcessBeforeInitialization()方法被调用。
6).若bean指定了ini-method方法、,它将被调用。
7).最后,若有BeanPostProcessor和bean关联,则它们的postProcessAfterInitialization()方法被调用、。
示例代码一: BeanPostProcessor 注册bean后处理器,能给所有bean做初始和收尾工作,等效于在xml文件中配置init-method="ini" destroy-method="release"。
如果bean构造时 需要调用有参的构造函数,可以在constructor-arg 中配置。
ByeService.java , javabean
public class ByeService {
private String bye ;
public String getBye() {
return bye;
}
public void setBye(String bye) {
this.bye = bye;
}
public void sayBye(){
System.out.println(bye);
}
}
GreetingService.java, javabean
public class GreetingService implements BeanNameAware,BeanFactoryAware{
private String greeting ;
private String greeting2 ; /* byeService */
private ByeService bs ; public GreetingService(ByeService bs){
this.bs = bs ;
System.out.println("Constructor: new GreetingService()");
}
public GreetingService(String str1,String str2){
System.out.println("1111");
}
public GreetingService(String str1,Integer str2){
System.out.println("2222");
}
public GreetingService(String str1,int str2){
System.out.println("3333");
}
public GreetingService(int str1,String str2){
System.out.println("4444");
} /**
* beannameAware,注入bean的id
*/
public void setBeanName(String name) {
System.out.println("BeanNameAware:setBeanName() : " + name);
} /**
* bean工厂关注
*/
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware:setBeanFactory() : " + beanFactory);
} public ByeService getBs() {
return bs;
} public void setBs(ByeService bs) {
this.bs = bs;
System.out.println("DI:setBs() : " + bs);
} public String getGreeting() {
return greeting;
} public void setGreeting(String greeting) {
this.greeting = greeting;
System.out.println("DI:setGreeting() : " + greeting);
} public void sayGreeting(){
bs.sayBye();
}
public void sayGreeting2(){
System.out.println(greeting2);
} public String getGreeting2() {
return greeting2;
} public void setGreeting2(String greeting2) {
this.greeting2 = greeting2;
System.out.println("DI:setGreeting2() : " + greeting2);
} /**
* 定制初始化方法
*/
public void ini(){
System.out.println("ini");
} /**
* 定制销毁方法
*/
public void release(){
System.out.println("release");
}
}
MyBeanPostProcessor.java, bean的后处理器
public class MyBeanPostProcessor implements BeanPostProcessor { /**
* 后处理
*/
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor:after:" + beanName);
return bean;
} /**
* 之前处理
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor:before:"+beanName);
return bean;
}
}
applicationContext.xml 配置文件
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 欢迎服务 -->
<bean id="greetingService" class="cn.itcast.spring.service.GreetingService"
scope="singleton"
init-method="ini"
destroy-method="release">
<constructor-arg index="1" type="java.lang.String" value="12" />
<constructor-arg index="0" type="int" value="24" />
<property name="greeting">
<value>hello world</value>
</property>
<property name="greeting2" value="tom" />
<property name="bs" ref="byeService" />
</bean>
<!-- 欢送服务 -->
<bean id="byeService" class="cn.itcast.spring.service.ByeService">
<property name="bye">
<value>later</value>
</property>
</bean> <!-- 注册bean后处理器 -->
<bean id="myBeanPostProcessor" class="cn.itcast.spring.beanprocessor.MyBeanPostProcessor" />
</beans>
App.java
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");//src下 不需要加全路径
GreetingService gs = (GreetingService) ac.getBean("greetingService");
gs.sayGreeting();
gs.sayGreeting2();
ByeService bs = (ByeService) ac.getBean("byeService");
bs.sayBye();
((ClassPathXmlApplicationContext)ac).destroy();
}
}
3. 集合装配bean
单例和原型模式:
prototype、singleton、request session、global-session ,spring中的bean缺省情况下是单例模式。始终返回一个实例。若想返回不同的实例的话需要定义成原型模式。bean的singleton属性告诉上下文该bean是否为单例的。缺省为true。若为false的话,为原型bean。
<bean id="foo" class="...Foo" singleton="false"/>
<!– spring2.5 -->
<bean scope="prototype|single|..">
<bean id="foo" class="...Foo" autowire="autowire type">
有四种自动装配类型:
1.byName:寻找和属性名相同的bean,若找不到,则装不上。
2.byType:寻找和属性类型相同的bean,找不到,装不上,找到多个抛异常。
3.constructor:查找和bean的构造参数一致的一个或多个bean,若找不到或找到多个,抛异常。按照参数的类型装配
4.autodetect:(3)和(2)之间选一个方式。不确定性的处理与(3)和(2)一致。(选择标准:是否有含参的构造函数,没有则是byType)
<bean id="bar" class="Bar" autowire="byName"/>
<!-- spring2.5 -->
@Autowired
<bean class="...
AutowiredAnnotationBeanPostProcessor">
示例代码二: (通过util定义集合bean需要手动添加 spring-util-2.5.xsd)
PopSet.java, javabean
public class PopSet {
private String[] ss ;
private List list ;
private Set set ;
private Map map ;
private Properties prop ;
.....省略 get set方法
}
popSet.xml 配置文件, java bean中的 prop 对应到配置文件中用标签<prop> </prop>配置。
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd ">
<bean id="popSet" class="cn.itcast.spring.popset.PopSet">
<property name="ss">
<list>
<value>1</value>
<value>tom</value>
</list>
</property>
<property name="list" ref="myList" />
<property name="set">
<set>
<value>1</value>
<value>tom</value>
<ref bean="byeService"/>
<ref bean="byeService"/>
<bean class="cn.itcast.spring.service.ByeService">
<property name="bye" value="kk" />
</bean>
<bean class="cn.itcast.spring.service.ByeService">
<property name="bye" value="kk" />
</bean>
</set>
</property>
<property name="map">
<map>
<entry key="key001" value="tom" />
<entry key="key002" value-ref="byeService" />
<entry key="key003">
<bean class="cn.itcast.spring.service.ByeService" />
</entry>
</map>
</property>
<property name="prop">
<props>
<prop key="key001">tom</prop>
<prop key="key002">tom1</prop>
<prop key="key003">tom2</prop>
</props>
</property>
</bean> <bean id="byeService" class="cn.itcast.spring.service.ByeService">
<property name="bye" value="over" />
</bean> <!-- 通过util定义集合bean -->
<util:list id="myList">
<value>1</value>
<value>2</value>
<value>tom</value>
<ref bean="byeService"/>
<ref bean="byeService"/>
<bean class="cn.itcast.spring.service.ByeService">
<property name="bye" value="kk" />
</bean>
<bean class="cn.itcast.spring.service.ByeService">
<property name="bye" value="kk" />
</bean>
</util:list>
</beans>
App.java
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"cn/itcast/spring/popset/popSet.xml");
ac.getBean("popSet");
}
}
4.分散装配
将配置文件分成几个分散的配置文件。如配置数据库的 jdbc.properties文件。使用占位符变量代替bean装配文件中的硬编码配置。占位符采${variable}形式。
定制属性编辑器 , 如下利用自定义的编辑器能将 省市县装配到homeAddress对应的属性中去。
<property name="homeAddress">
<value>湖南省.长沙市.宁乡县.花明楼镇</value>
</property>
示例代码三:
Address.java, javabean
public class Address {
private String province;
private String city;
private String street;
private String zipCode;
......省略 set get方法
}
Scatter.java, javabean
public class Scatter {
private String driverClass ;
private String url ;
private String username ;
private String password ; private Address comAddress ;//公司地址
private Address homeAddress ;//家庭地址 }
jdbc.properties 分散配置的 prop文件
jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
AddressEditor.java 自定义编辑器
public class AddressEditor extends PropertyEditorSupport { public void setAsText(String text) throws IllegalArgumentException {
if(text != null && text.length() > 0){
String[] ss = text.split("\\.");
if(ss != null && ss.length > 3){
Address a = new Address();
a.setProvince(ss[0]);
a.setCity(ss[1]);
a.setStreet(ss[2]);
a.setZipCode(ss[3]);
//将转换成的地址对象设置给相应的属性上
setValue(a);
}
else{
setValue(null);
}
}
else{
setValue(null);
}
}
}
scatter.xml 配置文件
<?xml version="1.0"?>
<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" 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 ">
<!-- 分散配置(属性占位符配置器)
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:cn/itcast/spring/scatter/jdbc.properties</value>
</list>
</property>
</bean>
--> <!-- 自定义编辑器配置器 -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<!-- 自定义编辑器集 -->
<property name="customEditors">
<map>
<entry key="cn.itcast.spring.scatter.Address">
<bean class="cn.itcast.spring.editor.AddressEditor" />
</entry>
</map>
</property>
</bean> <bean id="scatter" class="cn.itcast.spring.scatter.Scatter">
<property name="driverClass" value="${jdbc.driverclass}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- -->
<property name="comAddress">
<bean class="cn.itcast.spring.scatter.Address">
<property name="province" value="jilin" />
<property name="city" value="cc" />
<property name="street" value="${jdbc.url}" />
</bean>
</property>
<property name="homeAddress">
<value>${jdbc.driverclass}.cc.renmin.139988</value>
</property>
</bean> <!-- 分散配置,加载分散配置的文件 -->
<context:property-placeholder location="classpath:cn/itcast/spring/scatter/jdbc.properties"/>
</beans>
App.java
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"cn/itcast/spring/scatter/scatter.xml");
ac.getBean("scatter");
}
}
Spring -- 入门,装备集合,自动装配,分散装配,自定义编辑器的更多相关文章
- Spring入门(6)-使用注解装配
Spring入门(6)-使用注解装配 本文介绍如何使用注解装配. 0. 目录 使用Autowired 可选的自动装配 使用Qualifier选择 1. 使用Autowired package com. ...
- Spring入门(八):自动装配的歧义性
1. 什么是自动装配的歧义性? 在Spring中,装配bean有以下3种方式: 自动装配 Java配置 xml配置 在这3种方式中,自动装配为我们带来了很大的便利,大大的降低了我们需要手动装配bean ...
- IDEA一步步创建Maven管理的Spring入门程序
目前,做Java开发的很多人都在使用IDEA了,而有些人也选择用Eclipse,我这里介绍一下IDEA一步步创建Maven项目的步骤,并创建一个Spring的入门程序(Java项目,非Web项目),讲 ...
- Spring入门(5)-自动装配Bean属性
Spring入门(5)-自动装配Bean属性 本文介绍如何装配Bean属性. 0. 目录 ByName ByType constructor 默认自动装配 混合使用自动装配和显示装配 1. ByNam ...
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring入门(二):自动化装配bean
Spring从两个角度来实现自动化装配: 组件扫描(component scanning):Spring会自动发现应用上下文中需要创建的bean. 自动装配(autowiring):Spring会自动 ...
- [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring学习(六)-----Spring使用@Autowired注解自动装配
Spring使用@Autowired注解自动装配 在上一篇 Spring学习(三)-----Spring自动装配Beans示例中,它会匹配当前Spring容器任何bean的属性自动装配.在大多数情况下 ...
- Spring自动装配----注解装配----Spring自带的@Autowired注解
Spring自动装配----注解装配----Spring自带的@Autowired注解 父类 package cn.ychx; public interface Person { public voi ...
随机推荐
- 【BZOJ3190】[JLOI2013]赛车 单调栈+几何
[BZOJ3190][JLOI2013]赛车 Description 这里有一辆赛车比赛正在进行,赛场上一共有N辆车,分别称为个g1,g2……gn.赛道是一条无限长的直线.最初,gi位于距离起跑线前进 ...
- Oracle Instant Client的安装和使用
转自:https://www.cnblogs.com/chinalantian/archive/2011/09/09/2172145.html 根据自己需求到Oracle网站(http://www.o ...
- 【Charles】使用教程+破解+Windows版本https乱码+https证书安装注意
一.使用教程参考: 这一篇就够了,其他都是大同小异.Windows版和MAC版使用没太多区别. Charles 从入门到精通 | 唐巧的博客 https://blog.devtang.com/2015 ...
- Logstash Reference Getting started with Logstash
进阶功能_Logstash_数据采集_用户指南_日志服务-阿里云 https://help.aliyun.com/document_detail/49025.html Logstash Referen ...
- 命令行操作flask
Flask-Script 先安装pip3 install Flask-Script from sansa import create_app from flask_script import Mana ...
- shell判断文件/目录是否存在
https://www.cnblogs.com/37yan/p/6962563.html caution!!! if should be end with fi caution!!! there sh ...
- 《CNI specification》翻译
Overview 本文提出了一个通用的基于插件的Linux容器网络解决方案,容器网络接口,CNI.它脱胎于旨在满足大多数rtk网络设计的rtk Networking Proposal. 首先,我们对如 ...
- 品牌管理之万变与不变——From 品牌管理培训
- GSM/GPRS/3G/4G
1.状态机机制的gprs拨号 像GPRS/3G模块之类的应用,需要连接,登陆,初始化等步骤完成后才能传输数据,而这些步骤又比较耗时. 所以用 状态机 + 超时 的机制来实现比较合理. 如下代码片段来描 ...
- python1变量,表达式和语句
1.变量和类型 变量是指向各种类型值的名字,以后再用到某个值时,直接引用这个名字即可,不用再写具体的值,在python中,变量的使用环境非常宽松,没有明显的变量声明,而且类型不是固定的.如果你不能确定 ...