Spring 官网:https://spring.io/
什么是Spring?
Spring 是一款 分层的Java SE/EE 的全栈、轻量级开源框架,以IOC和AOP为内核。
Spring的意义?
作为我们普通JAVA开发者,Spring 贯穿了我们整个开发生命,将来我们项目,可能100%都是用的Spring的框架
他是 我们Java 开发者 经典学习典范!
什么是IOC 和 AOP
- IOC 控制反转:反转的是Bean的创建权。
- AOP 面向切面:在程序运行时,动态将代码织入到类的指定方法、指定位置上。(很多日志框架都是这个思想)
我们目前用的 基本都是 Spring 5 的版本
Spring的优势
- 方便解耦,简化开发
- AOP编程支持
- 声明式事务支持
- 方便程序的测试(继承junit)
- 方便集成其他框架(Struts、Hibemate、Mybatis、Quartz定时任务框架)
- 降低JavaEE API的 难度使用
Spring 做了什么?
- 读取xml 配置文件
- 根据xml的 标识 获取Bean的 全限定类名
- 通过反射创建Bean对象
- 返回对象
Spring 快速入门
- 引入 Spring的核心Maven 仓库的包
- 编写Dao接口 和实现类
- 创建xml,并将Bean 配置到xml 中
- 然后 通过Spring API,创建出这个对象
操作
快速入门代码下载
下载后运行结果:
代码语言:javascript复制save runing....
Spring配置文件
代码语言:javascript复制例如:
<bean id="userDao" class="com.zanglikun.dao.impl.UserDaoImpl" scope="singleton"></bean>
id 不允许重复
class 全限定类名 (方便后期Spring帮我们创建对象)
Bean对象 必须存在无参构造
scope :
- singleton 单例 Bean的创建时间:当容器初始化即初始化,容器销毁,Bean销毁。容器在,Bean在,容器死,Bean亡
- prototype 多例 Bean的创建时间:每次getBean时,初始化。只要对象使用中,就会存在,如果对象不使用了,就会被JVM的GC回收
依赖注入DI 是 Spring 框架核心IOC(控制反转)的体现
Bean 依赖注入的方式
- 构造方法
- set方法
Spring 相关的API
getBean() API
- 可以传入Bean ID 或者 字节码文件 (推荐)
- 通过 字节码 获取Bean 如果有多个 Bean 那么就会报错!!!
配置数据源
- 导入 数据源坐标 和 数据源驱动坐标
- 创建数据源对象
- 设置数据源的基本连接数据
- 使用数据源获取连接资源和归还连接资源
<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>5.1.38</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
jdbc.properties
代码语言:javascript复制jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=740969606
配置文件
代码语言:javascript复制import com.alibaba.druid.pool.DruidDataSource;
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.ResourceBundle;
/**
* @author : zanglikun
* @date : 2021/3/18 10:55
* @Version: 1.0
* @Desc : 数据源测试
*/
public class DataSourcesTest {
// c3p0 数据源
@Test
public void test1() throws PropertyVetoException, SQLException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setUser("root");
dataSource.setPassword("740969606");
Connection connection = dataSource.getConnection();
System.out.println(connection); //com.mchange.v2.c3p0.impl.NewProxyConnection@30c7da1e
connection.close();
}
// druid 数据源
@Test
public void test2() throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setUsername("root");
dataSource.setPassword("740969606");
Connection connection = dataSource.getConnection();
System.out.println(connection); //com.mysql.jdbc.JDBC4Connection@61443d8f
connection.close();
}
// druid 配置文件抽取
@Test
public void test3() throws SQLException {
// 配置文件的名称 没有后缀
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");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection); //com.mysql.jdbc.JDBC4Connection@61443d8f
connection.close();
}
}
正文来了
导入坐标 pom文件
代码语言:javascript复制 <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
创建配置文件 applicationContext.xml
代码语言:javascript复制 <bean id="dataSources" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"></property>
<property name="user" value="root"></property>
<property name="password" value="740969606"></property>
</bean>
如果是解耦使用配置文件更替数据库账号和密码 就追加 彩色部分内容
代码语言:javascript复制 引入 context的约束头 更变最终结果是
<?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">
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="dataSources" 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>
测试
代码语言:javascript复制 // 测试 Spring 容器产生数据源对象
@Test
public void test4() throws SQLException {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
// sql 包下的
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection); // com.mchange.v2.c3p0.impl.NewProxyConnection@4d826d77
}
Spring 注解开发
spring是轻代码、重配置的框架,有些浪费时间。所以,我们就需要使用最新的趋势 — 注解 来代替 xml中的 bean 配置
Spring 原始注解
在需要创建Bean的各个类上假如注解 但是Spring 无法识别在那个包下面,故需要 引入下面配置去扫包
代码语言:javascript复制 <!-- 使用注解开发,需要配置组件扫描 这样 Spring就能知道被注解修饰的内容-->
<context:component-scan base-package="com.zanglikun"/>
如果无法配置好了扫描包范围,如果仍然报错 NoSuchBeanDefinitionException
请检查注解是否使用正确!!!,在检查注入的BeanID 是否正确!!!
@Component注解 用于实例化Bean 但是 可读性很差
我们在 Service层 、Dao层、Controller层 都用这个,我们就无法知道到底当前类是那一层,所以 建议使用@Controller、@Service、@Repository 来进行区分
@Autowired注解 与 @Qualifiter注解 区别
- 都是注入 Bean
- 当使用类型注入,单个 @Autowired 就够
- 当使用名称注入,如果有多个 必须使用@Autowired @Qualifiter 注入
@Resource注解 是什么
等价于 @Autowired @Qualifiter
@Value注解 作用
直接从容器中找 你Spring表达式的Key 例如
代码语言:javascript复制@Value("${jdbc.username}")
String username;
直接赋值 没什么用
代码语言:javascript复制@Value("zhangsan")
String username;
将来 sout username 的时候 就是zhangsan
@Scope注解 是说明
Spring产生的Bean是单例还是多例
代码语言:javascript复制@Scope("singleton")
@Scope("prototype")
@PostContruct注解 与 @PreDestory注解
用于方法上面,声明 Bean创建前执行的方法,与声明Bean销毁前执行的方法
Spring 新注解
@Configuration注解
作用范围: 类上 ,声明当前类是Spring核心配置类
@ComponentScan注解
作用范围: 类上,声明当前配置类扫描的区域
@Bean注解
将当前方法的返回值 已指定的名称存储到Spring容器中
@PropertySources注解
引入额外的配置文件,例如jdbc.properties
代码语言:javascript复制@PropertySources(classpath:jdbc.properties)
请搭配Spring原注解 @Value("${jdbc.username}") 使用
@Import注解
代码语言:javascript复制从核心配置文件 引入其他配置文件
@Import([Config1.class,Config2.class])
将来项目启动的时候 请使用
代码语言:javascript复制ApplicationContext app = new AnnotationConfigApplicationContext(核心配置类.class);
Spring 集成 Junit
这样 即搭建好了环境,将来直接注入 就可调用方法 进行测试
步骤
- 导入Spring集成的Junit 坐标
- 使用@RunWith注解 代替原来运行期
- @ContextConfigration 指定配置文件 或配置类
- 使用@Autowird 注入 使用的Bean 对象
- 测试
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
创建
代码语言:javascript复制import com.zanglikun.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;
/**
* @author : zanglikun
* @date : 2021/3/19 15:01
* @Version: 1.0
* @Desc : 切记 使用Spring 测试的版本 要与当前Spring版本保持一致
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunit {
@Autowired
UserService userService;
@Test
public void test1(){
userService.save();
}
@Test
public void test2(){
System.out.println(dataSource);
}
}
完成
接下来 为了避免将来查看繁琐,请跳转到下篇文章查看
https://cloud.tencent.com/developer/article/1935519
特殊说明:
解决问题的光鲜,藏着磕Bug的痛苦。
万物皆入轮回,谁也躲不掉!
以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!