SpringIOC
Spring的xml配置
Spring程序开发步骤
①导入 Spring 开发的基本包坐标
pom.xml
<!-- 1 导入spring-context -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
②编写 Dao 接口和实现类
UserDao
package com.itheima.dao;
public interface UserDao {
void save();
}
UserDaoImpl
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class UserDaoImpl implements UserDao {
public void save(){
System.out.println("save running......");
}
}
③创建 Spring 核心配置文件
在resource 目录下 选择 spring config 创建applicationContext.xml文件
④在 Spring 配置文件中配置 UserDaoImpl
applicationContext.xml 中配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
</beans>
⑤使用 Spring 的 API 获得 Bean 实例
package com.itheima.demo;
import com.itheima.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserDaoDemo {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)app.getBean("userDao");
userDao.save();
}
}
//输出-------------
save running......
dao层
Bean标签范围配置
scope:指对象的作用范围,取值如下:
取值范围 | 说明 |
---|---|
singleton | 默认值,单例的 |
prototype | 多例的 |
request | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中 |
session | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中 |
global session | WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session |
1)当scope的取值为singleton时
Bean的实例化个数:1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
对象创建:当应用加载,创建容器时,对象就被创建了
对象运行:只要容器在,对象一直活着
对象销毁:当应用卸载,销毁容器时,对象就被销毁了
2)当scope的取值为prototype时
Bean的实例化个数:多个
Bean的实例化时机:当调用getBean()方法时实例化Bean
对象创建:当使用对象时,创建新的对象实例
对象运行:只要对象在使用中,就一直活着
对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了
import com.itheima.dao.UserDao;
import jdk.jfr.StackTrace;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTset {
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); // scope="singleton" 单例 在此时创建bean
UserDao userDao1 = (UserDao)app.getBean("userDao"); // scope="prototype" 多例 在此时创建bean
UserDao userDao2 = (UserDao)app.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
/*
scope="singleton" 单例
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton"></bean>
输出 一样
com.itheima.dao.impl.UserDaoImpl@4efac082
com.itheima.dao.impl.UserDaoImpl@4efac082
scope="prototype" 多例
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="prototype"></bean>
输出 不一样
com.itheima.dao.impl.UserDaoImpl@4659191b
com.itheima.dao.impl.UserDaoImpl@55634720
*/
}
}
Bean生命周期配置
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
- 在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="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
</beans>
- UserDaoImpl 编写方法
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl创建.....");
}
public void init() {
System.out.println("初始化方法");
}
public void destory() {
System.out.println("销毁方法");
}
public void save() {
System.out.println("save running......");
}
}
- 测试
import com.itheima.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTset {
@Test
public void test1(){
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao)app.getBean("userDao");
System.out.println(userDao1);
app.close();
}
}
//----------------------
初始化方法
com.itheima.dao.impl.UserDaoImpl@72e5a8e
销毁方法
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 无参构造 实例化
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
-->
<!-- 工厂静态方法实例化 执行指定方法
<bean id="userDao" class="com.itheima.factory.StaticFactory" factory-method="getUserDao"></bean>
-->
<!-- 工厂实例方法实例化 -->
<bean id="factory" class="com.itheima.factory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
</beans>
1) 使用无参构造方法实例化
它会根据默认无参构造方法来创建类对象,如果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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
</beans>
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl创建.....");
}
public void init() {
System.out.println("初始化方法");
}
public void destory() {
System.out.println("销毁方法");
}
public void save() {
System.out.println("save running......");
}
}
import com.itheima.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTset {
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao)app.getBean("userDao");
System.out.println(userDao1);
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 工厂静态方法实例化 执行指定方法 -->
<bean id="userDao" class="com.itheima.factory.StaticFactory" factory-method="getUserDao"></bean>
</beans>
package com.itheima.factory;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
public class StaticFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
import com.itheima.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTset {
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao)app.getBean("userDao");
System.out.println(userDao1);
}
}
3) 工厂实例方法实例化
工厂的非静态方法返回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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 工厂实例方法实例化 -->
<bean id="factory" class="com.itheima.factory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
</beans>
package com.itheima.factory;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
public class DynamicFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
import com.itheima.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTset {
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao)app.getBean("userDao");
System.out.println(userDao1);
}
}
业务层
Bean的依赖注入入门 --对象引用
set方法
1 创建 UserService,UserService 内部在调用 UserDao的save() 方法
package com.itheima.service;
public interface UserService {
public void save();
}
UserServiceImpl调用 UserDao
package com.itheima.service.impl;
import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
// spring注入userDao;不用再写
// ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
// UserDao userDao = (UserDao)app.getBean("userDao");
userDao.save();
}
}
配置Spring容器调用set方法进行注入
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
注:
name=“userDao” —》为 setUserDao 方法 去掉set 首字母小写
ref=“userDao” --》为 userDao 引用地址
测试类
package com.itheima.demo;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService =(UserService) app.getBean("userService");
userService.save();
/*
UserService userService = new UserServiceImpl();
userService.save();
不使用容器,直接new UserServiceImpl 会java.lang.NullPointerException
因为 UserServiceImpl save方法没有获取到userDao
*/
}
}
set方法:P命名空间注入
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入P命名空间:
xmlns:p=“http://www.springframework.org/schema/p”
其次,需要修改注入方式
<?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="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
<!--
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
-->
<!-- 精简上面写法-->
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
</beans>
构造方法注入
<?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="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
</beans>
package com.itheima.service.impl;
import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
Bean的依赖注入的数据类型
普通属性
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class UserDaoImpl implements UserDao {
private String username;
private int age;
public void setUsername(String username) {
this.username = username;
}
public void setAge(int age) {
this.age = age;
}
public void save() {
System.out.println(username + "=====" + age);
System.out.println("save running......");
}
}
注入普通属性username,password
<?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">
<!-- 注入 username = zhangsan ; age=18 -->
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="username" value="zhangsan"/>
<property name="age" value="18"/>
</bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
</beans>
测试
package com.itheima.demo;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService =(UserService) app.getBean("userService");
userService.save();
}
}
//---------------------------
zhangsan=====18
save running......
注入集合
package com.itheima.domian;
public class User {
private String name;
private String addr;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", addr='" + addr + '\'' +
'}';
}
}
集合对象
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
import com.itheima.domian.User;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class UserDaoImpl implements UserDao {
private List<String > strlist;
private Map<String , User> userMap;
private Properties properties;
public void setStrlist(List<String> strlist) {
this.strlist = strlist;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
/*
private String username;
private int age;
public void setUsername(String username) {
this.username = username;
}
public void setAge(int age) {
this.age = age;
}
public UserDaoImpl() {
System.out.println("UserDaoImpl创建.....");
}
public void init() {
System.out.println("初始化方法");
}
public void destory() {
System.out.println("销毁方法");
}
*/
public void save() {
// System.out.println(username + "=====" + age);
System.out.println(strlist);
System.out.println(userMap);
System.out.println(properties);
System.out.println("save running......");
}
}
集合注入
<?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="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="username" value="zhangsan"/>
<property name="age" value="18"/>
</bean>
-->
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<!-- 集合注入-->
<property name="strlist">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<!-- map注入-->
<property name="userMap">
<map>
<entry key="u1" value-ref="user1"></entry>
<entry key="u2" value-ref="user2"></entry>
</map>
</property>
<!-- properties注入 -->
<property name="properties">
<props>
<prop key="p1">ppp1</prop>
<prop key="p2">ppp2</prop>
<prop key="p3">ppp3</prop>
</props>
</property>
</bean>
<bean id="user1" class="com.itheima.domian.User">
<property name="name" value="tom"/>
<property name="addr" value="天津"/>
</bean>
<bean id="user2" class="com.itheima.domian.User">
<property name="name" value="marry"/>
<property name="addr" value="北京"/>
</bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
</beans>
测试结果
package com.itheima.demo;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService =(UserService) app.getBean("userService");
userService.save();
}
}
//----输出-------------
[aaa, bbb, ccc]
{u1=User{name='tom', addr='天津'}, u2=User{name='marry', addr='北京'}}
{p1=ppp1, p2=ppp2, p3=ppp3}
save running......
引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
引入其他配置文件
<import resource="applicationContext-user.xml"/>
总结
spring相关API
ApplicationContext 创建容器
- ApplicationContext的继承体系
applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
- ApplicationContext的实现类
1)ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件 推荐使用这种.
2)FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
3)AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
package com.itheima.demo;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
// 从类的根路径下加载配置文件 推荐使用
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//从磁盘路径上加载配置文件
//ApplicationContext app = new FileSystemXmlApplicationContext("G:\\javaEE_Http\\http_web\\Spring\\itheima_spring_ioc\\src\\main\\resources\\applicationContext.xml");
UserService userService =(UserService) app.getBean("userService");
userService.save();
}
}
getBean()方法使用
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("userService");
UserService userService2 = applicationContext.getBean(UserService.class);
资料文件
Spring注解开发
项目名:itheima_spring_anno
配置数据源
- 数据源(连接池)的作用
数据源(连接池)是提高程序性能如出现的
事先实例化数据源,初始化部分连接资源
使用连接资源时从数据源中获取
使用完毕后将连接资源归还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等
数据源的手动创建
①导入mysql数据库驱动坐标 及 c3p0和druid数据源的坐标
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.itheima</groupId>
<artifactId>itheima_spring_anno</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 导入相关依赖包 数据库及连接池 -->
<dependencies>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- junit测试框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
② 创建连接池
text1,text2 为直接读取数据
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
//测试手动创建druid数据源
public void test2() throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db1");
dataSource.setUsername("root");
dataSource.setPassword("root");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
//测试手动创建c3p0数据源
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/db1");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
② 创建连接池
text3 为读取配置文件数据
jdbc.properties 配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.username=root
jdbc.password=root
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
//测试手动创建c3p0数据源(加载properties配置文件)
public void test3() throws Exception {
//读取配置文件 properties
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
//创建数据源对象,设置连接参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
Spring配置数据源
- 1导入坐标 spring
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.itheima</groupId>
<artifactId>itheima_spring_anno</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 导入相关依赖包 数据库及连接池 -->
<dependencies>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- junit测试框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 导入spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
- 2 配置数据 c3p0 连接池
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="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>
- 3 测试
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
//测试spring容器产生数据源对象
public void test4() throws Exception {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
Spring抽取jdbc配置文件
首先,需要引入context命名空间和约束路径:
命名空间:xmlns:context=“http://www.springframework.org/schema/context”
约束路径:http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
Spring容器加载properties文件
<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>
- 2 配置数据 c3p0 连接池
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:contexe="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">
<!-- 加载外部properties文件-->
<contexe:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
- 3 测试
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
//测试spring容器产生数据源对象
public void test4() throws Exception {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
注解开发
Spring原始注解主要是替代的配置
注解 | 说明 |
---|---|
@Component | 使用在类上用于实例化Bean |
@Controller | 使用在web层类上用于实例化Bean |
@Service | 使用在service层类上用于实例化Bean |
@Repository | 使用在dao层类上用于实例化Bean |
@Autowired | 使用在字段上用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
spring 的xml配置
dao层
package com.itheima.dao;
public interface Userdao {
public void save();
}
package com.itheima.dao.impl;
import com.itheima.dao.Userdao;
public class UserDaoImpl implements Userdao {
@Override
public void save() {
System.out.println("save running");
}
}
service层
package com.itheima.service;
public interface UserService {
public void save();
}
package com.itheima.service.impl;
import com.itheima.dao.Userdao;
import com.itheima.service.UserService;
public class UserServiceImpl implements UserService {
private Userdao userDao;
public void setUserDao(Userdao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
Controller层
package com.itheima.web;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
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="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
spring的注解配置 @Component
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:contexe="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">
<!-- 配置组件扫描 -->
<contexe:component-scan base-package="com.itheima"/>
</beans>
dao层
package com.itheima.dao.impl;
import com.itheima.dao.Userdao;
import org.springframework.stereotype.Component;
// <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements Userdao {
@Override
public void save() {
System.out.println("save running");
}
}
service层
package com.itheima.service.impl;
import com.itheima.dao.Userdao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
// <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
@Component("userService")
public class UserServiceImpl implements UserService {
// <property name="userDao" ref="userDao"></property>
@Autowired
@Qualifier("userDao")
private Userdao userDao;
public void setUserDao(Userdao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
注解配置 @Controller,@Service ,@Repository
@Controller,@Service ,@Repository 功能同@Component; 但可读性比较好
package com.itheima.dao.impl;
import com.itheima.dao.Userdao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
// <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
//@Component("userDao")
@Repository("userDao") //功能同Component一样,仅可读性更好
public class UserDaoImpl implements Userdao {
@Override
public void save() {
System.out.println("save running");
}
}
package com.itheima.service.impl;
import com.itheima.dao.Userdao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
// <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
//@Component("userService")
@Service("userService") //功能同Component一样,仅可读性更好
public class UserServiceImpl implements UserService {
// <property name="userDao" ref="userDao"></property>
@Autowired // 按照数据类型,从spring容器中进行匹配 ; 可不写@Qualifier
@Qualifier("userDao") //按照id值从容器中进行匹配,但是必须和@Autowired一起使用
//@Resource(name = "userDao") 相当于 @Qualifier + @Qualifier
private Userdao userDao;
/* 使用注解,可以不写;但xml必须写
public void setUserDao(Userdao userDao) {
this.userDao = userDao;
}
*/
@Override
public void save() {
userDao.save();
}
}
注解配置 @Autowired,@Qualifier,@Repository
@Autowired,@Qualifier,@Repository
@Autowired // 按照数据类型,从spring容器中进行匹配 ; 可不写@Qualifier
@Qualifier("userDao") //按照id值从容器中进行匹配,但是必须和@Autowired一起使用
//@Resource(name = "userDao") 相当于 @Qualifier + @Qualifier
private Userdao userDao;
注解配置 --普通数据注入
- @Value 的使用
package com.itheima.service.impl;
import com.itheima.dao.Userdao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
@Service("userService") //使用方式同Component一样,仅可读性更好
public class UserServiceImpl implements UserService {
@Value("${jdbc.url}")
private String driver;
@Autowired // 按照数据类型,从spring容器中进行匹配 ; 可不写@Qualifier
@Qualifier("userDao") //按照id值从容器中进行匹配,但是必须和@Autowired一起使用
private Userdao userDao;
@Override
public void save() {
System.out.println(driver);
userDao.save();
}
}
package com.itheima.web;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
//--------------------
jdbc:mysql://localhost:3306/db1
save running
- @Scope 对象单例/多例
package com.itheima.dao.impl;
import com.itheima.dao.Userdao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("userDao")
//@Scope("protoype") 多例
@Scope("singleton") //单例
public class UserDaoImpl implements Userdao {
@Override
public void save() {
System.out.println("save running");
}
}
等同于applicationContext.xml中 scope 配置
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
- @PostConstruct ,@PreDestroy
导入包pro.xml
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
注解代码
package com.itheima.service.impl;
import com.itheima.dao.Userdao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Service("userService") //使用方式同Component一样,仅可读性更好
public class UserServiceImpl implements UserService {
@Value("${jdbc.url}")
private String driver;
@Autowired // 按照数据类型,从spring容器中进行匹配 ; 可不写@Qualifier
@Qualifier("userDao") //按照id值从容器中进行匹配,但是必须和@Autowired一起使用
private Userdao userDao;
@Override
public void save() {
System.out.println(driver);
userDao.save();
}
@PostConstruct
public void init(){
System.out.println("UserService对象的初始化方法");
}
@PreDestroy
public void destory(){
System.out.println("UserService对象的销毁方法");
}
}
等同于applicationContext.xml中 init-method,destroy-method
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
测试
package com.itheima.web;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
app.close();
}
}
//--------------------
UserService对象的初始化方法
jdbc:mysql://localhost:3306/db1
save running
UserService对象的销毁方法
spring新注解
使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:
非自定义的Bean的配置:
加载properties文件的配置:context:property-placeholder
组件扫描的配置:context:component-scan
引入其他文件:
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解 |
@ComponentScan | 用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“com.itheima”/>一样 |
@Bean | 使用在方法上,标注将该方法的返回值存储到 Spring 容器中 |
@PropertySource | 用于加载.properties 文件中的配置 |
@Import | 用于导入其他配置类 |
package com.itheima.config;
import org.springframework.context.annotation.*;
/**
* 核心配置 总配置
*/
@Configuration //标志该类是spring的核心配置类
@ComponentScan("com.itheima") // <contexe:component-scan base-package="com.itheima"/>
//@PropertySource("classpath:jdbc.properties") // <contexe:property-placeholder location="classpath:jdbc.properties"/>
@Import(DataSoureCofiguration.class) // import 多个文件可使用数组
public class SpringCofiguration {
}
package com.itheima.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/**
* 数据源项目配置
*/
@PropertySource("classpath:jdbc.properties")
// <contexe:property-placeholder location="classpath:jdbc.properties"/>
public class DataSoureCofiguration {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.usernasme}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSoure") //spring 会将当前方法的返回值以指定的名称存储到spring容器中
public DataSource getDataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
package com.itheima.web;
import com.itheima.config.SpringCofiguration;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class UserController {
public static void main(String[] args) {
//以注解配置容器对象时,读取
ApplicationContext app = new AnnotationConfigApplicationContext(SpringCofiguration.class);
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
//----------------------------
spring集成junit
①导入spring集成的Junit的坐标 spring-test
pom.xml
<!--此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
②使用@Runwith注解替换原来的运行期
③使用@ContextConfiguration指定配置文件或配置类
④使用@Autowired注入需要测试的对象
⑤创建测试方法进行测试
package com.itheima.test;
import com.itheima.config.SpringCofiguration;
import com.itheima.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.sql.DataSource;
import java.sql.SQLException;
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml") //使用配置文件加载 创建容器
@ContextConfiguration(classes = {SpringCofiguration.class})
public class SprintJunitTest {
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1() throws SQLException {
userService.save();
System.out.println(dataSource.getConnection());
}
}