Spring(一)
1.1 Spring框架的概述
1.1.1什么是Spring
- Spring是分层的JavaSE和JavaEES一站式轻量级开源框架。
- 分层:
- SUN提供的EE的三层结构:web层、业务层、数据访问层(持久层、集成层)。
- Struts2是web层基于MVC设计模式框架。
- Hibernate是持久层的一个ORM框架。
- 一站式:
- Spring框架有对三层的每层解决方案:
- web层:Spring MVC。
- 持久层:JDBC Template。
- 业务层:Spring的Bean管理。
- 分层:
1.1.2Spring的核心
- IOC(Inverse of control):控制反转。
- 控制反转:将对象的创建权,交由Spring管理。
- IOC原理:
- AOP(Aspect Oriented Programming):面向切面编程。
- 面向切面编程:是面向对象的功能延伸,不是替换面向对象,是用来解决面向对象的一些问题。
1.1.3Spring的版本
- Spring3.x版本和Spring4.x版本。Spring4.x版本需要整合Hibernate4.x版本。
1.1.4EJB:企业级的JavaBean
- EJB:SUN公司提出的EE解决方案。
1.1.5Spring的优点
- 方便解耦,简化开发
- Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交由Spring管理。
- AOP编程的支持
- Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
- 声明式事务的支持
- 只需要通过配置就可以完成对事务的管理,无需手动编程。
- 方便程序的测试
- Spring对Junit4支持,可以通过注解方便的测试Spring程序。
- 方便集成各种优秀框架
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
- 降低JavaEE API的使用难度
- Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使得这些API应用难度大大降低。
1.2 Spring的入门
1.2.1Spring的体系结构
- Spring框架是一个分层架构,它包含了一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分。
1.2.2下载Spring的开发包
- spring-framework-3.2.0.RELEASE-dist.zip --Spring开发包
- docs:Spring框架的API和规范。
- libs:Spring开发的jar包。
- schema:XML的约束文档。
- spring-framework-3.0.2.RELEASE-dependencies.zip --Spring开发中的依赖包
1.2.3创建web工程并引入相应的jar包。
- Core Container:
- spring-beans-3.2.0.RELEASE.jar
- spring-core-3.2.0.RELEASE.jar
- spring-context-3.2.0.RELEASE.jar
- spring-expression-3.2.0.RELEASE.jar
- 开发的日志记录的jar包:
- com.springsource.org.apache.commons.logging-1.1.1.jar 用于整合其他的日志的jar包(类似于Hibernate中的slf4j)
- com.springsource.org.apache.log4j-1.2.15.jar
1.2.4创建Spring的配置文件
- 在src下新建一个applicationContext.xml文件
- 引入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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
1.2.5引入log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=info, stdout
1.2.6体验传统开发和Spring开发
- 创建一个接口:HelloService.java。
package cn.spring3.demo1; /** * 入门的案例 */ public interface HelloService { public void sayHello(); }
- 创建一个实现类:HelloServiceImpl.java。
package cn.spring3.demo1; public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("Hello Spring"); } }
- 传统方式开发--多态
@Test //传统方式 public void demo1(){ HelloService helloService = new HelloServiceImpl(); helloService.sayHello(); }
- Spring开发
- 要在applicationContext.xml文件中配置<bean>标签
<!--
通过<bean>标签设置类的信息,通过id属性为类起个标识
-->
<bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
- 要在applicationContext.xml文件中配置<bean>标签
- 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 通过<bean>标签设置类的信息,通过id属性为类起个标识 --> <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/> </beans>
- 测试代码
@Test //Spring开发 public void demo2(){ //创建一个工厂类 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl"); helloService.sayHello(); }
1.2.7IOC和DI的区别?
- IOC:控制反转,将对象的创建权,交由Spring管理。
- DI:依赖注入,在Spring创建对象的过程之中,把对象的属性注入到类中。
- 面向对象中对象之间的关系
- 依赖:
- 面向对象中对象之间的关系
public class A{ private B b; }
- 继承:is a。
- 聚合:
- 聚集
- 组合
- 示例:
- HelloService.java类
package cn.spring3.demo1; /** * 入门的案例 */ public interface HelloService { public void sayHello(); }
- HelloServiceImpl.java类
package cn.spring3.demo1; public class HelloServiceImpl implements HelloService { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override public void sayHello() { System.out.println("Hello"+info); } }
- 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 通过<bean>标签设置类的信息,通过id属性为类起个标识 --> <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"> <!-- 使用 <property>标签注入属性--> <property name="info" value="Spring"></property> </bean> </beans>
- 测试代码
@Test //Spring开发 public void demo2(){ //创建一个工厂类 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl"); helloService.sayHello(); }
1.2.8Spring框架加载配置文件
- ApplicationContext(应用上下文),加载Spring框架配置文件。
- 加载classpath:
- new ClassPathXmlApplicationContext("applicationContext.xml"); :加载classpath下面配置文件。
- 加载磁盘路径:
new FileSystemXmlApplicationContext("applicationContext.xml"); :加载磁盘下配置文件。
- 加载classpath:
1.2.9BeanFactory和ApplicationContext区别?
- ApplicationContext类继承了BeanFactory。
- BeanFactory在使用到这个类的时候,getBean()方法才会加载到这个类。(延迟加载)。
- ApplicationContext类加载配置文件的时候,创建所有的类。
- ApplicationContext对BeanFactory提供了扩展的功能。
- 国际化处理。
- 事件传递。
- Bean自动装配。
- 各种不同应用层的Context实现。
- ****早期开发使用BeanFactory。
1.2.10MyEclipse配置XML提示
- 复制Schema的Location。
- windows--preferences--XML Catalog
1.3 IOC装配Bean
1.3.1Spring框架Bean实例的方式:
- 提供了三种方式实例化Bean。
- 构造方法实例化:(默认无参数)--反射
- <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
- 构造方法实例化:(默认无参数)--反射
package cn.spring3.demo2; /** * 使用无参数的方法实例化 */ public class Bean1 { }
<bean id="bean1" class="cn.spring3.demo2.Bean1"></bean>
@Test //无参数的构造方法实例化 public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean1 bean1= (Bean1) applicationContext.getBean("bean1"); System.out.println(bean1); }
- 静态工厂方法实例化(简单工厂模式)--反射+简单工厂
package cn.spring3.demo2; /** * 使用静态工厂实例化 */ public class Bean2 { }
package cn.spring3.demo2; /** * Bean2的静态工厂 */ public class Bean2Factory { public static Bean2 getBean2Instance(){ return new Bean2(); } }
<bean id="bean2Factory" class="cn.spring3.demo2.Bean2Factory" factory-method="getBean2Instance" ></bean>
@Test //使用静态工厂实例化 public void demo2(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean2 bean2= (Bean2) applicationContext.getBean("bean2Factory"); System.out.println(bean2); }
- 实例工厂实例化(工厂方法模式) ---反射+实例工厂
package cn.spring3.demo2; /** * 使用实例工厂 */ public class Bean3Factory { public Bean3 getBean3Instance(){ return new Bean3(); } }
package cn.spring3.demo2; /** * 使用实例工厂实例化 */ public class Bean3 { }
<!-- 用来初始化Bean3Factory --> <bean id="bean3Factory" class="cn.spring3.demo2.Bean3Factory"></bean> <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3Instance" ></bean>
@Test //使用实例工厂实例化 public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean3 bean3= (Bean3) applicationContext.getBean("bean3"); System.out.println(bean3); }
- 分析:
- 构造方法实例化:(默认无参数)--反射
- 直接给Spring一个完整的类名,Spring就会帮助我们实例化对象。
- 静态工厂方法实例化(简单工厂模式)
- 要给一个factory-method,因为静态方法可以直接通过类名.方法()的形式来调用方法,而class="",当然是静态工厂的类名了,因为只有这样Spring才能帮助我们初始化工厂,返回需要的实例化对象。
- 实例工厂实例化(工厂方法模式)
- 之所以要实例化工厂,因为实例工厂不是静态工厂,不可以通过类名.方法()的形式调用方法,所以必须先让Spring来实例化实例工厂,然后再告诉Spring实例工厂的对象名是什么以及什么方法来实例化对象的。
- 构造方法实例化:(默认无参数)--反射
1.3.2Bean的其他配置
- id和name的区别
- id遵守XML约束的id的约束。id约束保证这个属性的值是唯一的,而且必须以字母开始,可以使用字母、数字、连字符、下划线、句号、冒号。
- name没有这些要求
- 如果bean标签上没有配置id,那么name可以作为id。
- 早期开发的时候,Spring整合Struts1,"/login"是特殊字符,只能使用name。
- <bean name="/login"/>
- 现在的开发中都使用id属性即可。
- 类的作用范围:
- scope属性:
- singleton:单例的。(默认值)
- prototype:多例的。
- request:web开发中使用。创建一个对象,将这个对象存入request范围,request.setAttribute()。
- session:web开发中使用。创建一个对象,将这个对象存入session范围,session.setAttribute()。
- globalSession:一般用于Porlet应用环境,指的是分布式开发。不是Porlet环境,globalSession等同于session。
- 实际开发中主要使用的是singleton和prototype。
- scope属性:
- Bean的生命周期
- 配置Bean的初始化的销毁的方法
- init-method="setUp"。
- destory-method="teardown" 。
- 执行销毁的时候,必须手动关系工厂,而且支队scope="singleton"有效。
- 配置Bean的初始化的销毁的方法
- 示例:
- Product.java
- 示例:
package cn.spring3.demo3; public class Product { //初始化的方法 public void setup(){ System.out.println("初始化的方法"); } //销毁的方法 public void teardown(){ System.out.println("销毁的方法"); } }
- applicationContext.xml
<bean id="product" class="cn.spring3.demo3.Product" init-method="setup" destroy-method="teardown"/>
- 测试代码:
@Test //测试初始化和销毁的方法 public void demo1(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Product product = (Product) applicationContext.getBean("product"); applicationContext.close(); }
- Bean的生命周期的11个步骤:
- instantiate bean对象示例化。
- populate properties 封装属性。
- 如果Bean实现BeanNameAware 执行setBeanName。
- 如果Bean实现BeanFactoryAware或者ApplicationContextAware设置工厂setBeanFactory或者上下文对象setApplicationContext。
- 如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization。
- 如果Bean实现initializingBean,执行afterPropertiesSet。
- 调用<bean init-method="init"> 指定初始化方法init。
- 如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization。
- 执行业务处理。
- 如果Bean实现DisposableBean,执行destory。
- 调用<bean destory-method="destory">,指定销毁方法destory。
1.3.3Bean中属性的注入
- Spring支持构造器注入和setter()方法注入。
- 构造器注入
package cn.spring3.demo4; public class Car { private String name; private Double price; public Car(){} public Car(String name, Double price) { super(); this.name = name; this.price = price; } @Override public String toString() { return "Car [name=" + name + ", price=" + price + "]"; } }
<!-- bean的属性注入 --> <bean id="car" class="cn.spring3.demo4.Car" > <constructor-arg index="0" value="宝马" /> <constructor-arg index="1" value="300000.0"/> </bean>
@Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Car car = (Car) applicationContext.getBean("car"); System.out.println(car);; }
- setter()方法注入
- 普通属性
- setter()方法注入
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
<bean id="car2" class="cn.spring3.demo4.Car2"> <property name="name" value="宝马"/> <property name="price" value="300000.0"/> </bean>
@Test public void demo2(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Car2 car2 = (Car2) applicationContext.getBean("car2"); System.out.println(car2);; }
- 对象属性
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
package cn.spring3.demo4; public class Person { private String name; private Car2 car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car2 getCar() { return car; } public void setCar(Car2 car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", car=" + car + "]"; } }
<bean id="car2" class="cn.spring3.demo4.Car2"> <property name="name" value="宝马"/> <property name="price" value="300000.0"/> </bean> <bean id="person" class="cn.spring3.demo4.Person"> <property name="name" value="神经病"/> <property name="car" ref="car2"/> </bean>
@Test public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) applicationContext.getBean("person"); System.out.println(person);; }
- 命名空间p注入属性
- 为了简化XML的文件配置,Spring从2.5开始引入了一个新的p名称空间。
- p:属性名="xxx" 引入常量值。
- p:属性名-ref="xxx" 引入其他bean对象
- 命名空间p注入属性
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
package cn.spring3.demo4; public class Person { private String name; private Car2 car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car2 getCar() { return car; } public void setCar(Car2 car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", car=" + car + "]"; } }
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car2" class="cn.spring3.demo4.Car2" p:name="宝马" p:price="200000.0"/> <bean id="person" class="cn.spring3.demo4.Person" p:name="神精病" p:car-ref="car2"/> </beans>
@Test public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) applicationContext.getBean("person"); System.out.println(person);; }
- SPEL: Spring Expression Language,Spring表达式语言,对依赖注入进行简化。
- 语法:#{表示式}
- <bean id="" value="#{}"/>
- SPEL: Spring Expression Language,Spring表达式语言,对依赖注入进行简化。
package cn.spring3.demo5; public class Product { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="product" class="cn.spring3.demo5.Product" > <property name="name" value="#{'哇哈哈'}"></property> </bean> </beans>
@Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Product product = (Product) applicationContext.getBean("product"); System.out.println(product.getName()); }
1.3.4集合属性的注入
package cn.spring3.demo6; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class CollectionDemo { private List<String> list; private Set<String> set; private Map<String, Integer> map; private Properties properties; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Map<String, Integer> getMap() { return map; } public void setMap(Map<String, Integer> map) { this.map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } }
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="collectionDemo" class="cn.spring3.demo6.CollectionDemo"> <property name="list"> <list > <value>哈哈</value> <value>呵呵</value> </list> </property> <property name="set"> <set> <value>嘻嘻</value> <value>笨笨</value> </set> </property> <property name="map"> <map> <entry key="你好" value="1"/> </map> </property> <property name="properties"> <props> <prop key="哈哈">呵呵</prop> </props> </property> </bean> </beans>
package cn.spring3.demo6; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); CollectionDemo c = (CollectionDemo) applicationContext.getBean("collectionDemo"); System.out.println(c.getList()); System.out.println(c.getSet()); System.out.println(c.getMap()); System.out.println(c.getProperties()); } }
1.3.5加载配置文件
- 第一种写法:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml","bean2.html");
- 第二种写法
<import resource="applicationContext2.xml"/>
1.4 IOC容器装配Bean(注解方式)
1.4.1Spring的注解装配Bean
package cn.demo1; import org.springframework.stereotype.Component; @Component("userService") public class UserService { public void sayHello(){ System.out.println("Hello World"); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.demo1"/> </beans>
package cn.demo1; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.sayHello(); } }
- 除了@Component外,Spring提供了3个功能基本和@Component等效的注解。
- @Repository用于对DAO实现类进行标注
- @Service用于对Service实现类进行标注
- @Controller用于对Controller实现类进行标注
1.4.2Bean属性的注入
- 普通属性
- @value()
package cn.demo1; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("userService") public class UserService { @Value("世界") private String info; public void sayHello(){ System.out.println("Hello " +info); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.demo1"/> </beans>
package cn.demo1; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.sayHello(); } }
- 对象属性
- @AutoWired:自动装配默认使用类型注入
- @Qualifier("") 按名称进行注入
- @Resource等价于@Autowired和@Qualifier(),是按照名称进行注入。
- @AutoWired:自动装配默认使用类型注入
package cn.demo2; import org.springframework.stereotype.Repository; @Repository public class UserDAO { public void show() { System.out.println("这是数据访问层"); } }
package cn.demo2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("userService") public class UserService { @Autowired private UserDAO userDAO; public void show(){ userDAO.show(); System.out.println("这是业务层"); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.demo2"/> </beans>
package cn.demo2; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.show(); } }
package cn.demo2; import org.springframework.stereotype.Repository; @Repository("userDAO") public class UserDAO { public void show() { System.out.println("这是数据访问层"); } }
package cn.demo2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service("userService") public class UserService { @Autowired @Qualifier("userDAO") private UserDAO userDAO; public void show(){ userDAO.show(); System.out.println("这是业务层"); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.demo2"/> </beans>
package cn.demo2; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.show(); } }
package cn.demo2; import org.springframework.stereotype.Repository; @Repository("userDAO") public class UserDAO { public void show() { System.out.println("这是数据访问层"); } }
package cn.demo2; import javax.annotation.Resource; import org.springframework.stereotype.Service; @Service("userService") public class UserService { @Resource(name="userDAO") private UserDAO userDAO; public void show(){ userDAO.show(); System.out.println("这是业务层"); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.demo2"/> </beans>
package cn.demo2; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.show(); } }
1.4.3Bean其他属性的配置
- 在XML文件配置中配置初始化和销毁方法
- init-method和destory-method。
- 在注解中配置初始化和销毁
- @PostConstruct
- @PreDestroy
- 配置Bean的作用范围
- @Scope
1.4.4Spring的XML和注解的结合使用
- XML:bean管理。
- 注解:注入属性的时候比较方便。
- 两种方式结合:一般使用XML注册Bean,使用注解进行属性的注入。
1.5 Spring整合web开发
package cn.demo3; import org.springframework.stereotype.Service; @Service("userService") public class UserService { public void show(){ System.out.println("Hello Spring"); } }
package cn.demo3; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @SuppressWarnings("serial") public class UserServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.show(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn"/> </beans>
- 正常整合Servlet和Spring是没有问题的
- 但是每次执行Servlet的时候都会加载Spring配置,加载Spring环境。
- 解决方法
- 在Servlet的init方法中加载Spring配置文件,但是这种方法不是很好,因为其他Servlet用不了。
- 将加载信息内容放到ServletContext域中,ServletContext对象是全局对象,服务器启动的时候创建,在创建ServletContext的时候就加载Spring配置文件,即Spring环境。
- 使用ServletContextLinstener:用于监听ServletContext对象的创建和销毁的监听器,使用它可以帮助我们完成我们所需要的功能。
- 庆幸的是,Spring提供了web整合包spring-web-3.2.0.RELEASE.jar就已经帮助我们实现了。
- 导入jar包:spring-web-3.2.0.RELEASE.jar
- public class ContextLoaderListener extends ContextLoader implements ServletContextListener {}可以看出实现了ServletContextListener接口。
- 而Spring默认加载的是WEB-INF下的配置文件,我们可以从XmlWebApplicationContext类中观察到。
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; }
- 如何修改加载applicationContext.xml的位置,可以观察XmlWebApplicationContext类。
/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/ package org.springframework.web.context.support; import java.io.IOException; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.ResourceEntityResolver; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { } protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) for (String configLocation : configLocations) reader.loadBeanDefinitions(configLocation); } protected String[] getDefaultConfigLocations() { if (getNamespace() != null) { return new String[] { "/WEB-INF/" + getNamespace() + ".xml" }; } return new String[] { "/WEB-INF/applicationContext.xml" }; } }
- 在web.xml文件中配置如下内容:
<!-- 配置ServletContext监听器,用于服务器一启动就将Spring的配置信息放入ServletContext域对象之中 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 更改Spring读取applicationContext.xml配置文件的路径 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
1.6 Spring整合Junit
- 程序中导入Junit的jar包。
- 导入一个jar包,Spring与Junit整合的jar包。
- spring-test-3.2.0.RELEASE.jar。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class SpringTest { @Autowired private UserService userService; @Test public void demo1(){ userService.sayHello(); } }
最新文章
- Meteor + node-imap(nodejs) + mailparser(nodejs) 实现完整收发邮件
- java中采用dom4j解析xml文件
- ubuntu14.04显卡驱动问题(amd5600k集显7650d)
- spring多线程与定时任务
- matlab squeeze函数的用法
- [OrangePi] If you are using an older image
- Data
- WPF 之 文本框及密码框添加水印效果
- IE9中jquery发生Object未定义原因及解决办法
- 设置linux服务器定时与时间服务器同步
- IOS--UIAlertView的使用方法详细
- MongoDB--数据库与Collection注意事项
- 部署ionic开发环境
- IE兼容事件绑定V1.0
- idea设置JVM运行参数
- WinForm版图像编辑小程序(实现图像拖动、缩放、旋转、抠图)
- 联想笔记本BIOS设置中文详解
- 2014年10月Android面试总结
- python线程的GIL问题(全局解释器锁)
- js 温故而知新 用typeof 来判断一个未定义的变量