1 Spring

2022-01-19 13:31:59 浏览数 (1)

Spring 官网:https://spring.io/

什么是Spring?

Spring 是一款 分层的Java SE/EE 的全栈、轻量级开源框架,以IOCAOP为内核。

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 快速入门

  1. 引入 Spring的核心Maven 仓库的包
  2. 编写Dao接口 和实现类
  3. 创建xml,并将Bean 配置到xml 中
  4. 然后 通过Spring API,创建出这个对象

操作

快速入门代码下载

下载后运行结果:

代码语言:javascript复制
save runing....

Spring配置文件

代码语言:javascript复制
例如:
<bean id="userDao" class="com.zanglikun.dao.impl.UserDaoImpl" scope="singleton"></bean>

id 不允许重复

class 全限定类名 (方便后期Spring帮我们创建对象)

Bean对象 必须存在无参构造

scope :

  1. singleton 单例      Bean的创建时间:当容器初始化即初始化,容器销毁,Bean销毁。容器在,Bean在,容器死,Bean亡
  2. prototype 多例     Bean的创建时间:每次getBean时,初始化。只要对象使用中,就会存在,如果对象不使用了,就会被JVM的GC回收

依赖注入DI 是 Spring 框架核心IOC(控制反转)的体现

Bean 依赖注入的方式

  • 构造方法
  • set方法

Spring 相关的API

getBean() API

  1. 可以传入Bean ID 或者 字节码文件 (推荐)
  2. 通过 字节码 获取Bean 如果有多个 Bean 那么就会报错!!!

配置数据源

  • 导入 数据源坐标 和 数据源驱动坐标
  • 创建数据源对象
  • 设置数据源的基本连接数据
  • 使用数据源获取连接资源和归还连接资源
代码语言:javascript复制
        <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 对象
  • 测试
代码语言:javascript复制
        <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的痛苦。

万物皆入轮回,谁也躲不掉!

以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!

0 人点赞