Spring
Spring 是什么?
Spring 是于 2003 年兴起的一个轻量级的,IOC 和 AOP 的 Java 开发框架,它 是为了简化企业级应用开发而生的。
Spring 优点
轻量级:Spring框架使用的jar都比较小,一般在1M以下或者几百kb。Spring 核心功能所选的jar总共3M左右,框架运行占用资源较少,运行效率高。
非侵入式: 编写一些业务类的时候不需要继承 spring 特定类,通过配置完成依赖注入后就可以使用。
IOC (Inversion of Control),就是由 Spring IOC 容器管理对象,而 非传统实现中由程序代码直接操控,面向接口式编程,使得耦合度降低。
AOP:通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传 统 OOP 实现的功能可以通过 AOP 轻松应付在 Spring 中,开发人员可以从 繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高 开发效率和质量。
Spring Hello World 搭建
预备工作:
- 新建一个普通的java项目,命名为spring。
- 在项目中新建一个Modual,在modual中新建一个项目命名为 spring1。
- 在pom.xml的dependencies中添加常用jar包,如spring-context和junit等。
- 在resources下新建spring.xml,bean.xml
新建Phone类
package com.ff.spring.bean;
public class Phone {
}
新建user类
package com.ff.spring.bean;
public class User {
private int id;
private String name;
private Phone phone;
public User() {
System.out.println("构造方法");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
}
bean.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">
<import resource="bean.xml"></import>
</beans>
spring.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="com.ff.spring.bean.User" scope="singleton"></bean>
-->
<!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
<!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->
<bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
<bean id="user" class="com.ff.spring.bean.User" scope="prototype">
<property name="id" value="21"></property>
<property name="name" value="xaiom"></property>
<property name="phone" ref="phone"></property>
</bean>
新建一个测试类
package com.ff.spring.test;
import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
// 创建spring容器 ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user1 = (User) applicationContext.getBean("user");
System.out.println(user1);
User user2 = (User) applicationContext.getBean("user");
System.out.println(user2);
}
}
运行截图
因为 spring.xml的scope的值为prototype,因此每创建一个对象都执行一次构造方法,且每次使用时都会创建一个新的对象。
若将scope属性的值改为singleton,则一个项目中只有一个该对象,而且是在容器创建时就会创建对象执行一次构造方法。
eg2:使用set方法向属性注入值
新建Phone类
package com.ff.spring.bean;
public class Phone {
}
新建user类
package com.ff.spring.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class User {
private int id;
private String name;
private Phone phone;
private Set sett;
private List list;
private Map map;
private Properties properties;
public User() {
System.out.println("构造方法");
}
public User(int id) {
this.id= id;
}
public User(int id, String name) {
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
public Set getSett() {
return sett;
}
public void setSett(Set sett) {
this.sett = sett;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", phone=" + phone +
", sett=" + sett +
", list=" + list +
", map=" + map +
", properties=" + properties +
'}';
}
}
spring.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">
<import resource="bean.xml"></import>
</beans>
bean.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="com.ff.spring.bean.User" scope="singleton"></bean>
-->
<!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
<!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->
<!--XML 配置方式依赖注入 DI(Dependency Injection)
注入方式:1.set方式注入
2.用构造方法注入-->
<bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
<bean id="user" class="com.ff.spring.bean.User" scope="prototype">
<property name="id" value="21"></property>
<property name="name" value="xaiom"></property>
<property name="phone" ref="phone"></property>
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<value>list2</value>
</list>
</property>
<property name="sett">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="map">
<map>
<entry key="map1" value="map1"></entry>
<entry key="map2" value="map2"></entry>
<entry key="map3" value="map3"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="key1" >value1</prop>
<prop key="key2" >value2</prop>
<prop key="key3" >value3</prop>
</props>
</property>
</bean>
</beans>
</beans>
测试类
package com.ff.spring.test;
import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
// 创建spring容器 ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user1 = (User) applicationContext.getBean("user");
System.out.println(user1);
User user2 = (User) applicationContext.getBean("user");
System.out.println(user2);
}
}
运行截图
eg3:使用构造方法向属性注入值
Phone类
package com.ff.spring.bean;
public class Phone {
}
user类
package com.ff.spring.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class User {
private int id;
private String name;
private Phone phone;
private Set sett;
private List list;
private Map map;
private Properties properties;
public User() {
System.out.println("构造方法");
}
public User(int id) {
this.id= id;
}
public User(int id, String name) {
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
public Set getSett() {
return sett;
}
public void setSett(Set sett) {
this.sett = sett;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", phone=" + phone +
", sett=" + sett +
", list=" + list +
", map=" + map +
", properties=" + properties +
'}';
}
}
spring.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">
<import resource="bean.xml"></import>
</beans>
bean.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="com.ff.spring.bean.User" scope="singleton"></bean>
-->
<!-- scope 对象生产的作用域 scope="singleton" 一个项目中只有一个该对象,而且是在容器创建时就会创建对象-->
<!--scope="prototype" 原型的(多例的) 每次使用时都会创建一个新的对象,在get时创建-->
<!--XML 配置方式依赖注入 DI(Dependency Injection)
注入方式:1.set方式注入
2.用构造方法注入-->
<bean id="phone" class="com.ff.spring.bean.Phone" scope="prototype"></bean>
<bean id="user" class="com.ff.spring.bean.User" scope="singleton">
<constructor-arg name="id" value="111"></constructor-arg>
<constructor-arg name="name" value="xx"></constructor-arg>
</bean>
</beans>
测试类
package com.ff.spring.test;
import com.ff.spring.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
// 创建spring容器 ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user1 = (User) applicationContext.getBean("user");
System.out.println(user1);
User user2 = (User) applicationContext.getBean("user");
System.out.println(user2);
}
}
运行截图
eg4:使用注解的方式
复制spring1这个module,在项目根粘贴,命名为spring2,修改pom.xml中的name为spring2。
此时我们会发现这个复制出来的项目比原来创建的module字体颜色浅,需要做以下的设置。
file->Project Structure->Modules->"+"->import Module->选择spring2->Maven->改名字->apply->ok
Phone类
package com.ff.spring.bean;
public class Phone {
}
User类
package com.ff.spring.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class User {
private int id;
private String name;
private Phone phone;
private Set sett;
private List list;
private Map map;
private Properties properties;
public User() {
System.out.println("构造方法");
}
public User(int id) {
this.id= id;
}
public User(int id, String name) {
this.id= id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
public Set getSett() {
return sett;
}
public void setSett(Set sett) {
this.sett = sett;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", phone=" + phone +
", sett=" + sett +
", list=" + list +
", map=" + map +
", properties=" + properties +
'}';
}
}
userDao
package com.ff.spring.Dao;
import org.springframework.stereotype.Repository;
@Repository (value = "userDao")
public class UserDao {
public void save(){
System.out.println("保存员工信息");
}
}
UserService
package com.ff.spring.service;
import com.ff.spring.Dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
UserDao userDao;
public void save(){
userDao.save();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
spring.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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--spring开启注解扫描-->
<!--若加入下面这一行后有错,需要加约束条件
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
-->
<context:component-scan base-package="com.ff.spring"></context:component-scan>
</beans>
新建测试类:
package com.ff.spring.test;
import com.ff.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
IOC控制反转 也叫做反转控制
把创建对象的控制权反转给spring框架/容器
*/
public class Test2 {
public static void main(String[] args) {
// 创建spring容器 ClassPathXmlApplicationContext 一个实现类 ApplicationContext 上层接口
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
userService.save();
UserService userService1= applicationContext.getBean("userService",UserService.class);
userService1.save();
}
}
运行结果:
Spring JDBC
预备工作:
- 用上面的方式新建module命名为spring3
- 删除最下面的spring2.iml
在pom.xml中加jar的坐标
<?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>com.example</groupId>
<artifactId>spring2</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring3</name>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.6.2</junit.version>
</properties>
<dependencies>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>provided</scope>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- 阿里数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--spring-mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</project>
新建spring.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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--spring开启注解扫描-->
<context:component-scan base-package="com.ff.spring"></context:component-scan>
<import resource="db.xml"></import>
</beans>
新建db.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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--读取属性文件-->
<context:property-placeholder location="config.properties"></context:property-placeholder>
<!--spring生产数据库连接管理对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${drivername}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${uname}"></property>
<property name="password" value="${password}"></property>
<property name="initialSize" value="5"></property>
<property name="minIdle" value="5"></property>
<property name="maxActive" value="20"></property>
</bean>
<!--spring提供的jdbc支持-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
新建config.properties
drivername=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybaits?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
uname=root
password=13579
新建JdbcUtil.java
package com.ff.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class JdbcUtil {
public Connection getConnection() throws SQLException {
DruidDataSource druidDataSource= new DruidDataSource();
druidDataSource.setUrl("");
druidDataSource.setUsername("");
druidDataSource.setPassword("");
druidDataSource.setDriverClassName("");
return druidDataSource.getConnection();//从连接池中获取的
}
}
User
package com.ff.spring.bean;
import org.springframework.stereotype.Component;
@Component
public class User {
private int id;
private String name;
}
UserDao
package com.ff.spring.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void save(){
jdbcTemplate.update("insert into dept(name) values ('后勤部')");
}
}
新建UserService
package com.ff.spring.service;
import com.ff.spring.Dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service(value="userService")
public class UserService {
@Autowired
UserDao userDao;
public void save(){
userDao.save();
}
}
新建测试Test1
package com.ff.spring.test;
import com.ff.spring.bean.User;
import com.ff.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
ApplicationContext context= new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.save();
}
}
运行结果:
数据库中插入结果