共计 18461 个字符,预计需要花费 47 分钟才能阅读完成。
1、注解开发 - 上
1.1、创建一个新的项目
通过 maven 创建一个新的项目 spring004
1.2、导入 jar 包
在原有的 jar 包的基础上加入 spring-aop 的 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.tyshcool</groupId>
<artifactId>spring004</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.3</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
</project>
1.3、编写业务层与持久层
IManagerService.java
public interface IManagerService {public void findAll();
}
ManagerServiceImpl.java
import com.tyschool.spring004.manager.service.IManagerService;
public class ManagerServiceImpl implements IManagerService {public void findAll() {}}
IManagerDao.java
public interface IManagerDao {public void findAll();
}
ManagerDaoImpl.java
import com.tyschool.spring004.manager.dao.IManagerDao;
public class ManagerDaoImpl implements IManagerDao {public void findAll() {System.out.println("执行到了这里");
}
}
1.4、创建 applicationContext 文件
1.4.1、加入 context 约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
注解整合时,需要多导入一个 context 名称约束,可以通过 context 去导入包。
1.4.2、增加扫描包
<!--spring 创建对象时要扫描的包 -->
<context:component-scan base-package="com.tyschool.spring004.manager"></context:component-scan>
2、注解开发 - 下
2.1、配置对象
@Component(“beanName”)
相当于在 xml 中配置一个 bean。
2.1.1、修改业务层实现类
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.stereotype.Component;
@Component("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {@Autowired
private IManagerDao managerDaoImpl;
public void findAll() {managerDaoImpl.findAll();
}
}
2.1.2、修改持久层的实现类
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.stereotype.Component;
@Component("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {public void findAll() {System.out.println("执行到了这里");
}
}
2.2、测试
2.2.1、导入 jar 包
spring test 和 junit
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.2.RELEASE</version>
<scope>test</scope>
</dependency>
2.2.2、编写测试类
@Runwith 注解替换原来的运行期
@ContextConfifiguration 指定配置文件或配置类
@Autowired 注入需要测试的对象
STest.java
import com.tyschool.spring004.manager.service.IManagerService;
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;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest {@Autowired
private IManagerService managerServiceImpl;
@Test
public void findAll(){managerServiceImpl.findAll();
}
}
3、spring 常用注解(对象创建)
3.1、@Component
作用:
声明一个 Bean
属性:
value:默认 bean 的 id 是当前类的类名。首字母小写。可以通过 value 指定
@Component("managerDaoImpl")
3.2、@Controller、@Service、@Repository
@Controller 在展现层使用,控制器的声明(C)
@Service 在业务逻辑层使用(service 层)
@Repository 在数据访问层使用(dao 层)
3.2.1、修改业务层
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
//@Component("managerServiceImpl")
@Service("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {@Autowired
private IManagerDao managerDaoImpl;
public void findAll() {managerDaoImpl.findAll();
}
}
3.2.2、修改持久层
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//@Component("managerDaoImpl")
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {public void findAll() {System.out.println("执行到了这里");
}
}
测试
4、spring 常用注解(数据注入)- 上
4.1、@Autowired
作用:
注解注入各种类型,完成自动装配的工作。通过 @Autowired 的使用来消除 set,get 方法。
@Autowired
private IManagerDao managerDaoImpl;
如果这里不用 @Autowired 会报空指针异常。
4.2、@Qualifier
作用:
表明了哪个实现类才是我们所需要的,与 @Autowired() 一起使用
创建另一个 service
ManagerServiceImpl1.java
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.stereotype.Service;
@Service("managerServiceImpl1")
public class ManagerServiceImpl1 implements IManagerService {public void findAll() {System.out.println("这是另一个 service");
}
}
修改测试类
public class STest {@Autowired()
@Qualifier("managerServiceImpl")
private IManagerService ims ;
@Test
public void findAll(){ims.findAll();
}
}
4.3、@Resource
作用:
按照 Bean 的 id 注入
修改测试类:
public class STest {// @Autowired()
// @Qualifier("managerServiceImpl")
@Resource(name="managerServiceImpl1")
private IManagerService ims ;
@Test
public void findAll(){ims.findAll();
}
}
注意:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
与 @Autowired 区别:
@Autowired 与 @Resource 都可以用来装配 bean. 都可以写在字段上, 或写在 setter 方法上。
@Autowired 默认按类型装配(这个注解是属业 spring 的),默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false,如:@Autowired(required=false),如果我们想使用名称装配可以结合 @Qualifier 注解进行使用
@Resource(这个注解属于 JavaEE 的),默认按照名称进行装配,名称可以通过 name 属性进行指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在 setter 方法上默认取属性名进行装配。当找不到与名称匹配的 bean 时才按照类型进行装配。但是需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配。
5、spring 常用注解(数据注入)- 下
5.1、@Value
作用:
将我们配置文件的属性读出来,有 @Value(“”)、@Value(“${}”) 和 @Value(“#{}”) 三种方式
@Value(“”) 基本数据的填充
@Value(“${}”) 基于配置文件
@Value(“#{}”) 基于 SpEl 表达式
5.1.1、@Value(“”)
修改 ManagerDaoImpl.java 文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {@Value("路径")
private String path;
public void findAll() {System.out.println("执行到了这里");
System.out.println(path);
}
}
测试
文件与 URL 地址注入
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {@Value("路径")
private String path;
@Value("classpath:1.txt")
private Resource resource;// 用来存储资源
@Value("http://www.baidu.com")
private Resource resource1;
public void findAll() {System.out.println("执行到了这里");
System.out.println(path);
System.out.println(resource);
System.out.println(resource1);
}
}
注意:
boolean exists(); 用来判断资源是否存在
boolean isOpen();用来判断资源是否打开
URL getURL();如果底层资源可以表示成 URL,那么该方法可以返回一个 URL 对象。
File getFile();如果底层资源对应着一个文件,那么该方法可以返回一个 File 对象。
String getFilename();返回底层资源对应的文件名。
InputStream getInputStream();返回底层资源对应输入流。
5.1.2、@Value(“#{}”)
修改 ManagerDaoImpl.java 文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {@Value("#{'abcdefg'}")
private String str;
@Value("#{systemProperties['os.name']}")
private String systemname; // 注入操作系统属性
@Value("#{T(java.lang.Math).random() * 100.0}")
private double number; // 注入表达式结果
@Value("#{manager.uname}")
private String uname; // 注入其他 Bean 属性:注入 manager 对象的属性 uname,类具体定义见下面
public void findAll() {System.out.println("执行到了这里");
System.out.println(str);
System.out.println(systemname);
System.out.println(number);
System.out.println(uname);
}
}
Manager.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class Manager {private int mid;
@Value("你好")
private String uname;
private String pword;
private Date zcsj;
public int getMid() {return mid;
}
public void setMid(int mid) {this.mid = mid;
}
public String getUname() {return uname;
}
public void setUname(String uname) {this.uname = uname;
}
public String getPword() {return pword;
}
public void setPword(String pword) {this.pword = pword;
}
public Date getZcsj() {return zcsj;
}
public void setZcsj(Date zcsj) {this.zcsj = zcsj;
}
@Override
public String toString() {return "Manager{" +
"mid=" + mid +
", uname='" + uname + '\'' +
", pword='" + pword + '\'' +
", zcsj=" + zcsj +
'}';
}
}
5.1.3、@Value(“${}”)
创建 data.properties
s1=this is there
修改 applicationContext.xml 文件
<context:property-placeholder location="classpath:data.properties" />
修改 ManagerDaoImpl.java 文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {@Value("${s1}")
private String data;
public void findAll() {System.out.println("执行到了这里");
System.out.println(data);
}
}
6、spring 常用注解(作用范围)
6.1、@Scope
作用:
@Scope 注解是 SpringIOC 容器中的一个作用域,在 Spring IOC 容器中具有以下几种作用域:基本作用域 singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域
6.1.1、单例
singleton 单例模式 – 全局有且仅有一个实例
修改 STest.java 文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest {@Resource(name="managerServiceImpl")
private IManagerService ims ;
@Resource(name="managerServiceImpl")
private IManagerService ims1 ;
@Test
public void findAll(){System.out.println(ims);
System.out.println(ims1);
//ims.findAll();
}
}
6.1.2、多例
prototype 原型模式 – 每次获取 Bean 的时候会有一个新的实例
修改 ManagerServiceImpl.java 文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Scope(value = "prototype")
@Service("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {@Autowired
private IManagerDao managerDaoImpl;
@Value("这是一个 S")
private String s;
public void findAll() {managerDaoImpl.findAll();
}
}
测试
6.1.3、其他
request – request 表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP request 内有效
session – session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效
global session – global session 作用域类似于标准的 HTTP Session 作用域, 不过它仅仅在基于 portlet(Portlet 是基于 Java 的 Web 组件,由 Portlet 容器管理,并由容器处理请求,生产动态内容。如:单点登录)的 web 应用中才有意义
7、spring 常用注解(bean 生命周期)
7.1、@PostConstruct
作用:
实现初始化,相当于 init-method 属性
7.2、@PreDestroy
作用:
实现销毁,相当于 destroy-method 属性
7.3、测试
编写测试类 STest1.java 文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest1 {@Autowired
@Qualifier("managerServiceImpl")
private IManagerService ims;
public STest1(){System.out.println("ims:"+ims);
}
@PostConstruct
public void init(){System.out.println("init:"+ims);
}
@PreDestroy
public void destroy(){System.out.println("destroy:"+ims);
}
@Test
public void test(){//new STest1();
System.out.println("test:"+ims);
}
}
8、纯注解开发 - 上
8.1、配置问题
前面我们虽然使用了注解,但是我们还是使用了 xml 文件,如果解决 xml 文件问题?
8.2、@Configuration
作用:
用于指定配置类,当我们创建容器时,从指定的配置类中加载。
创建配置类
SpringApplicationContext.java
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringApplicationContext {
}
8.3、@ComponentScan
作用:
用于指定初始化容器时,要扫描的包。
修改配置类
SpringApplicationContext.java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.tyschool.spring004")
public class SpringApplicationContext {
}
删除配置文件 applicationContext.xml
8.4、@Bean
作用:
创建 Bean 对象,只能用在方法上。
创建连接池与 DBUtils 配置类
DbUtilsC3P0.java
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
public class DbUtilsC3P0 {// 配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){ComboPooledDataSource cds=new ComboPooledDataSource();
try {cds.setDriverClass("com.mysql.cj.jdbc.Driver");
cds.setJdbcUrl("jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC");
cds.setUser("root");
cds.setPassword("Root12345");
} catch (PropertyVetoException e) {e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);
}
}
9、纯注解开发 - 下
9.1、@PropertySource
作用:
加载配置文件(.properties),在书写路径时要加 classpath
9.1.1、配置文件优化一
修改 DbUtilsC3P0.java 文件
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
public class DbUtilsC3P0 {@Value("com.mysql.cj.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC")
private String url;
@Value("root")
private String username;
@Value("Root12345")
private String password;
// 配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){ComboPooledDataSource cds=new ComboPooledDataSource();
try {cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
} catch (PropertyVetoException e) {e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);
}
}
9.1.2、配置文件优化二
创建 db.properties 文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC
jdbc.username=root
jdbc.password=Root12345
修改 DbUtilsC3P0.java 文件
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
@PropertySource(value={"classpath:db.properties"},ignoreResourceNotFound = false)
public class DbUtilsC3P0 {@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){ComboPooledDataSource cds=new ComboPooledDataSource();
try {cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
} catch (PropertyVetoException e) {e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);
}
}
注意:
ignoreResourceNotFound 表示没有找到文件是否会报错,默认为 false,就是会报错,一般开发情况应该使用默认值,设置为 true 相当于生吞异常,增加排查问题的复杂性.
9.2、@Import
作用:
导入配置类
修改 DbUtilsC3P0.java 文件
@Configuration
@ComponentScan("com.tyschool.spring004")
@Import({DbUtilsC3P0.class})
public class SpringApplicationContext {
}
9.3、测试
修改 ManagerDaoImpl.java 文件
import com.tyschool.spring004.javabean.Manager;
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {@Autowired
private QueryRunner queryRunner;
public void findAll() {try {List<Manager> list=queryRunner.query("select * from manager", new BeanListHandler<Manager>(Manager.class));
for(Manager m:list){System.out.println(m);
}
} catch (SQLException e) {e.printStackTrace();
}
}
}
创建测试类 STest2.java 文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = com.tyschool.spring004.utils.SpringApplicationContext.class)
public class STest2 {@Resource(name="managerServiceImpl")
private IManagerService ims ;
@Test
public void findAll(){ims.findAll();
}
}