【Spring Framework】Spring入门教程(二)基于xml配置对象容器
基于xml配置对象容器——xml 标签说明
alias标签
作用:为已配置的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="user" class="org.cjw.pojo.User" />
<!--
标签alias:为已配置的bean设置别名
name属性:必要属性,代表为哪一个bena配置别名
此属性的值为其他bean标签的id或name属性值
alias属性:必要属性,代表新命名的别名是什么
-->
<alias name="user" alias="user1" />
</beans>
--测试代码
package org.cjw.pojo.test;
import org.cjw.pojo.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
@Test
public void testAlias() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过id获取User对象
User user = context.getBean("user", User.class);
System.out.println(user);
System.out.println("-----------------");
// 通过别名获取User对象
User user2 = context.getBean("user1", User.class);
System.out.println(user2);
}
}
--测试结果
bean标签的配置
5.2.1. bean标签作用
用于声明一个类,在启动Spring框架的时候根据配置信息创建对象到Spring容器里面。
5.2.2. 属性说明
<?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>标签:用于声明一个类,在启动Spring框架的时候配置信息创建对象到spring容器里面去
name属性:设置对象名(唯一标识符),可以有多个名称,每一个名称用逗号隔开,如name1,name2
id属性:设置对象名(唯一标识符),功能和name一样,但是id只能有一个
class属性:用于指定对象对应的类名,用于反射创建对象
scope属性:用于设置对象的作用范围,可选参数如下:
*singleton:单例(默认)
对象出生:当程序加载配置文件创建容器时,创建
对象活着:只要容器还在,一直活着
对象死亡:应用停止,容器销毁,对象死亡
*propertype:多例(原型对象)
对象出生:当程序加载配置文件创建容器时,创建
对象活着:只要对象被使用,一直活着
对象死亡:对象长时间不用,会被java立即回收机制回收
*request:web项目中,Spring将创建的对象放在request作用域中
*session:web项目中,Spring将创建的对象放在session作用域中
-->
<bean id="customerServiceImpl" class="org.cjw.service.impl.CustomerServiceImpl" scope="singleton" />
</beans>
5.2.3. Bean作用范围
作用范围也可以说生命周期(bean能存活多久)
<bean id="" class="" scope="作用域"/>
在开发中主要使用 scope="singleton"、 scope="prototype"
对于MVC中的Action/Controller使用prototype类型,其他使用singleton
<?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="" class="" scope="作用域"/>
scope : 配置当前bean的范围大小
singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean()
-->
<bean id="customerServiceImpl" class="org.cjw.service.impl.CustomerServiceImpl" scope="prototype" />
</beans>
在Web开发的三层架构中
-
Web:一般都是多例
-
Service:单例
-
DAO:单例
如果使用struct,那么会在表示层使用成员变量来接受前端发送过来的参数,此时如果表示层使用的是单例,那么会造成数据的错乱,所以表示层需要使用多例。
而现在springMVC已经不再使用成员变量来接受前端参数了,而是直接对应方法的参数,所以表示层可以使用单例,因为方法的参数是在程序运行过程中才会被赋值,所以不存在数据错乱的问题,因此可以使用单例。
单例和多例的使用判断准则:是否存在共享数据情况,如果有,使用多例,没有则单例。如果使用了单例还存在共享数据的情况,那么就需要使用锁来保证数据的正确性。
实例化Bean的四种方式
Spring创建对象的四种方式
5.3.1. 构造器实例化(无参数构造器),最标准,使用最多。
package org.cjw.pojo;
public class SomeBean1 {
public SomeBean1() {
System.out.println("SomeBean.SomeBean1()");
}
}
--配置文件
<!-- ①构造器实例化(无参构造器),最标准、使用最多 -->
<bean id="someBean1" class="org.cjw.pojo.SomeBean1"/>
5.3.2. 通过静态方法工厂创建(了解)
--bean、静态工厂类
SomeBean2、SomeBean2Factory
public class SomeBean2 {
public SomeBean2() {
System.out.println("SomeBean.SomeBean2()");
}
}
public class SomeBean2Factory {
public static SomeBean2 getSomeBean2() {
System.out.println("执行静态工厂方法");
return new SomeBean2();
}
}
--静态工厂配置
<!-- ②.静态工厂方法实例化:解决系统遗留问题 -->
<bean id="someBean2" class="org.cjw.factory.SomeBean2Factory" factory-method="getSomeBean2" />
5.3.3. 通过实例工厂创建(了解)
--实体工厂
public class SomeBean3 {
public SomeBean3() {
System.out.println("SomeBean.SomeBean3()");
}
}
public class SomeBean3Facotry {
//实例工厂方法
public SomeBean3 getSomeBean3() {
System.out.println("执行实例工厂方法");
return new SomeBean3();
}
}
--配置方式
<!-- 1.配置工厂bean -->
<bean id="someBean3Factory" class="org.cjw.factory.SomeBean3Facotry"></bean>
<!-- 2.配置bena
factory-bean : 创建bean的工厂对象对应的 id
factory-method : 工厂bean中返回 bean对象的方法
-->
<bean id="someBean3" factory-bean="someBean3Factory" factory-method="getSomeBean3"/>
5.3.4. 实现FactoryBean接口实例化:实例工厂变种(了解)
实现FactoryBean接口,MyBatis和Spring集成就是使用的这种方式。
此种方式,如果没有使用Bean对应的对象,Spring就不会自动创建,只有在使用的时候Spring才会创建对应的对象。
public class SomeBean4 {
public SomeBean4() {
System.out.println("SomeBean4.SomeBean4()");
}
}
public class SomeBean4ObjectFactory implements FactoryBean<SomeBean4> {
@Override
public SomeBean4 getObject() throws Exception {
SomeBean4 bean4 = new SomeBean4();
return bean4;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
--配置方式
<!-- ④.实现FactoryBean接口实例化:实例工厂变种:集成其他框架使用:LocalSessionFactoryBean -->
<bean id="someBean4" class="org.cjw.factory.SomeBean4ObjectFactory" />
初始化和销毁方法
比如DataSource,SessionFactory最终都需要关闭资源:在Bean销毁之前,都要调用close方法.
<bean id="someBean" class="......"
init-method="该类中初始化方法名" destroy-method="该类中销毁方法名">
</bean>
init-method:bean生命周期初始化方法,对象创建后就进行调用
destroy-method:容器被销毁的时候,如果bean被容器管理,会调用该方法。
default-init-method:指定默认的初始化方法
分析原理:
如果bean的scope="prototype",那么容器只负责创建和初始化,它并不会被spring容器管理。交给用户自己调用。
<?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"
default-init-method="init">
<!--
配置全局初始化方法,如果有100个bean中都有init方法,那么只要Spring容器一启动,bean对象一创建
默认对象中只要有 init方法,都全部会执行:一般不建议使用
-->
<!--
init-method : 配置初始化方法名
destroy-method : 配置销毁方法名
-->
<bean id="someBean" class="org.cjw.pojo.SomeBean1" init-method="init" destroy-method="destory" />
</beans>
获得properties文件的值
Spring配置文件支持通过xxx.properties文件的Key获得对应的值。实现该功能是通过${Key}来获得Properties文件指定Key的Value值。
使用Spring读取配置文件必须导入新的命名空间(context)。
导入命名空间方法:将命名空间和约束重新拷贝一份,将对应的全部替换成 context,然后关联context本地schema约束。
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
使用Spring创建阿里巴巴 Druid连接池(读取配置文件)
7.1.1. 拷贝Mysql驱动包和druid连接池jar包到项目中
7.1.2. 创建 db.properites
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/users
jdbc.username=root
jdbc.password=root
jdbc.maxActive=10
7.1.3. 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 读取classpath下的db.properties配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="${jdbc.maxActive}" />
</bean>
</beans>
7.1.4. 测试代码
@Test
public void testAlias() {
try {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = context.getBean("dataSource", DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
7.1.5. 效果
综合案例-模拟注册功能
此功能重点在于将每一层对象的创建交给Spring管理,对象之间的依赖关系交给Spring来维护。
Dao层接口以及实现代码
public interface UserDao {
public void insert(User user);
}
public class UserDaoImpl implements UserDao {
@Override
public void insert(User user) {
System.out.println("注册功能Dao层方法执行了");
}
}
Service层接口以及实现代码
public interface UserService {
void insert(User user);
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void insert(User user) {
System.out.println("注册功能Service层方法执行了");
userDao.insert(user);
}
}
Web表现层实现代码
package org.cjw.controller;
import org.cjw.pojo.User;
import org.cjw.service.UserService;
public class UserController {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void insert() {
System.out.println("注册功能Controller层方法执行了");
User user = new User();
userService.insert(user);
}
}
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="userController" class="org.cjw.controller.UserController">
<property name="userService" ref="userService" />
</bean>
<bean id="userService" class="org.cjw.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
<bean id="userDao" class="org.cjw.dao.impl.UserDaoImpl" />
</beans>
测试代码
@Test
public void testAlias() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserController userController = context.getBean("userController", UserController.class);
userController.insert();
}
测试结果
小结
1. 基于xml和ClassPathXmlApplicationContext配置容器
2. Spring读取 .Properteis配置文件
3. 综合案例-模拟注册功能-使用Spring管理对象