当前位置: 首页 > news >正文

速通Spring

尚硅谷2023最新版Spring6课程_bilibili

1 Spring

【强制】Spring是什么?

1) Spring是一款主流的Java EE轻量级开源框架。

    轻量级:体积很小,且不需要依赖于其他组件。

2) 狭义的Spring。

    Spring Framework。

3) 广义的Spring。

    以Spring Framework为核心的Spring技术栈。

4) Spring的核心思想。

    提供各种服务,以帮助我们简化基于POJO的Java应用程序开发。

【强制】Spring模块组成。

1) Spring Core。

    spring-core、spring-beans、spring-context、spring-expression。

2) Spring AOP。

    spring-aop、spring-aspects、spring-instrument。

3) Spring Data Access。

    spring-jdbc、spring-orm、spring-oxm、spring-jms、spring-tx。

4) Spring Web。

    spring-web、spring-webmvc、spring-websocket、spring-webflux。

5) Spring Message。

    spring-messaging。

6) Spring Test。

    spring-test。

2 Spring IoC

2.1 概念

【强制】IoC。

1) IoC:Inversion of Control,控制反转,是一种设计思想。

2) IoC的理念。

    让别人为你服务。原先是由程序员自己来包办关于对象的一切,现在让IoC Service Provider(IoC服务提供者)来负责。

3) IoC可以给我们带来什么?

    用一句话来概括就是,IoC是一种可以帮助我们解耦各业务对象间依赖关系的对象绑定方式。

【强制】DI。

1) DI:Dependency Injection,依赖注入。

    和IoC是一回事,只是观察的角度不同。

2) 依赖注入的实现方式。

    构造方法注入、setter方法注入。

【强制】IoC容器。

1) IoC容器是Spring对IoC Service Provider的实现。

    IoC Service Provider:IoC服务提供者,是一个概念。

    IoC Service Provider主要负责管理Java对象的实例化和初始化,控制对象与对象之间的依赖关系。

2) Spring提供了两种容器类型:BeanFactory和ApplicationContext。

    BeanFactory是IoC容器的基本实现,提供了 对象创建管理和依赖注入服务 两种特性。

    ApplicationContext是BeanFactory的子接口,在BeanFactory的基础上提供了 统一资源加载策略、国际化信息支持、容器内事件发布功能 等高级特性。

    我们开发人员可以无脑选择ApplicationContext。

3) ApplicationContext接口的常用实现类。

    ClassPathXmlApplicationContext。

    FileSystemXmlApplicationContext。

    ConfigurableApplicationContext。

    WebApplicationContext。

【强制】Bean。

1) IoC容器管理的Java对象称为Spring Bean。

2) bean的作用域。

    singleton:在IoC容器中有且仅有一个实例,默认。

    prototype:在IoC容器中可以有多个实例,每次获取都返回一个新的实例。

    request:在一个请求范围内有效。

    session:在一个会话范围内有效。

3) bean的生命周期(简化版本)。

    1. 创建bean。

        以反射或者CGLIB动态字节码生成方式(默认后者)获得目标类实例。

        以BeanWrapper对目标类实例进行包裹,返回BeanWrapper实例。

    2. 给bean设置属性(包括Aware相关依赖)。

    3. 调用bean的后置处理器-初始化前方法。

        执行自定义的BeanPostProcessor.postProcessBeforeInitialization方法。

    4. 初始化bean。

        执行自定义的init-method。

    5. 调用bean的后置处理器-初始化后方法。

        执行自定义的BeanPostProcessor.postProcessAfterInitialization方法。

    6. 使用bean。

    7. 销毁bean。

        关闭容器时,执行自定义的destory-method。

2.2 实践

【强制】获取bean。

1) 配置代码。

<bean id="myBean" class="com.mypath.MyBean"></bean>

2) Java代码。

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
// 1.根据ID获取bean
MyBean myBean1 = (MyBean)context.getBean("myBean");
// 2.根据类型获取bean(要求IoC容器中指定类型的bean有且仅有1个)
MyBean myBean2 = context.getBean(MyBean.class);
// 3.根据ID和类型获取bean
MyBean myBean3 = context.getBean("myBean", MyBean.class);

【强制】依赖注入。

1) 构造方法注入。

<bean id="student" class="com.mypath.Student"><constructor-arg index="0" value="llxz"></constructor-arg><constructor-arg index="1" ref="dream"></constructor-arg>
</bean>
<bean id="dream" class="com.mypath.Dream"></bean>

2) setter方法注入。

<bean id="student" class="com.mypath.Student"><property name="name" value="llxz"></property><property name="dream" ref="dream"></property>
</bean>
<bean id="dream" class="com.mypath.Dream"></bean>

【强制】自动绑定。

1) 手动绑定。

    使用<constructor-arg>或<property>为bean的属性注入依赖。

2) 自动绑定,也叫自动装配。

    通过<bean>的autowire属性,可以指定采用何种类型的自动绑定模式。

    Spring提供了5种自动绑定模式:no、byName、byType、constructor、autodetect。默认为no(手动绑定)。

3) 代码示例(byName)。

    Student.book自动绑定bean book。

class Student {private Book book;public void setBook(Book book) {this.book = book;}
}class Book {
}
<bean id="student" class="com.mypath.Student" autowire="byName"></bean>
<bean id="book" class="com.mypath.Book"></bean>

【推荐】FactoryBean。

1) 简介。

    FactoryBean是Spring提供的一种整合第三方框架的常用机制。配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性配置的类的实例,而是getObject()方法的返回值。工厂模式。

2) MyFactoryBean实现FactoryBean接口。

public class MyFactoryBean implements FactoryBean<MyBean> {@Overridepublic MyBean getObject() throws Exception {return new MyBean();}@Overridepublic class<?> getObjectType() {return MyBean.class;}
}

3) 配置bean。

<bean id="myBean" class="com.mypath.MyFactoryBean"></bean>

4) 获取bean。

ApplicationContext context = new ClassPathXmlApplicationContext("spring-factorybean.xml");
MyBean myBean = (MyBean) context.getBean("myBean");

2.3 基于注解开发

【强制】开启组件扫描。

1) 开启组件扫描。

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 开启组件扫描 --><context:component-scan base-package="com.mypath.mypackage"/>
</beans>

2) 组件扫描的目标注解。

    component-scan默认扫描的注解类型是@Component。

    在@Component 语义基础上细化后的@Repository、@Service、@Controller 也同样可以被component-scan扫描到。

3) 被添加到容器的组件的命名规则。

    component-scan在扫描相关类定义并将它们添加到容器时,会根据注解的value属性来生成beanName。默认的命名规则是 将类名首字母小写。

【强制】@Autowired。

1) @Autowired 按照类型匹配进行依赖注入。

    类似于byType类型的自动绑定,但它比byType更加灵活,可以标注在属性、方法、构造方法、构造方法参数上。

2) @Autowired 扫描。

    IoC容器需要某种方式来了解哪些对象标注了@Autowired,component-scan对此提供了支持。

3) @Qualifier。

    如果用byType方式同时找到多个同类型的对象实例,可以使用注解@Qualifier 对依赖注入的条件做进一步限定。

    @Qualifier 是byName自动绑定的注解版,可以单独使用,也可以和@Autowired 一起使用。

【强制】@Resource。

1) @Resource 是JDK扩展包提供的注解,更加具有通用性。

    除非是JDK 8,否则需要引入依赖。

<dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version>
</dependency>

2) @Resource 默认byName,未指定name时会使用属性名作为name。通过name找不到的话会尝试byType。

3) @Resource 用在属性、setter方法上。

【强制】全注解开发。

全注解开发就是不再使用Spring配置文件了,写一个配置类来代替配置文件。

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("com.mypath.mypackage")
public class MyConfig {
}

3 Spring AOP

3.1 概念

【强制】AOP。

1) AOP:Aspect-Oriented Programming,面向方面编程。

2) AOP可以给我们带来什么?

    使用AOP,我们可以对类似于日志记录和安全检查等系统需求进行模块化的组织。

3) AOP的实现机制。

    AOP的实现机制有动态代理、动态字节码增强、自定义类加载器、AOL扩展等。

    在Spring AOP中,在目标类实现了一些接口的情况下,使用基于接口的动态代理技术,否则使用基于类的CGLIB动态字节码增强技术。

【强制】动态字节码增强。

    通常的class文件都是从Java源代码文件使用Javac编译器编译而成的,但只要符含Java class规范,我们也可以使用ASM或者CGLIB等Java工具库,在程序运行期间,动态构建字节码的class文件。

    在此前提下,我们可以为需要织入横切逻辑的模块类在运行期间,通过动态字节码增强技术,为这些系统模块类生成相应的子类,而将横切逻辑加到这些子类中,让应用程序在执行期间使用的是这些动态生成的子类,从而达到将横切逻辑织入系统的目的。

    不过,如果需要扩展的类以及类中的实例方法等声明为final的话,则无法对其进行子类化的扩展。

    Spring AOP在无法采用动态代理机制进行AOP功能扩展的时候,会使用CGLIB库的动态字节码增强支持来实现AOP的功能扩展。

【强制】AOP基本概念。

1) Joinpoint。

    Jointpoint是可以进行织入操作的系统执行点。常见的Joinpoint类型有:方法调用、方法执行、构造方法调用、构造方法执行、字段设置、字段获取、异常处理执行、类初始化。

2) Pointcut。

    Pointcut是Jointpoint的表述方式。有点儿像引用。

    Pointcut的表述方式有:直接指定Joinpoint所在方法名称、正则表达式、使用特定的Pointcut表述语言。使用得比较普遍的是正则表达式。

3) Advice。

    Advice是单一横切关注点逻辑的载体,它代表将会织入到Jointpoint的横切逻辑。如果将Aspect比作OOP中的Class,那么Advice就相当于Class中的Method。

    按照Advice在Joinpoint位置执行时机的差异或者完成功能的不同,Advice可以分为:

    1. Before Advice:在Joinpoint指定位置之前执行的Advice。

    2. After returning Advice:只有在当前Joinpoint处执行流程正常完成后才执行。

    3. After throwing Advice:只有在当前Jointpoint处执行过程中抛出异常情况下才执行。

    4. After Advice:不管Joinpoint处执行流程是正常终了还是抛出异常都会执行。

    5. Around Advice:对附加其上的Joinpoint进行包裹,可以在Joinpoint之前和之后都指定相应的逻辑,甚至于中断或者忽略Joinpoint处原来程序流程的执行。我们常使用的Filter功能就是Around Advice的一种体现。

4) Aspect。

    Aspect是对系统中的横切关注点逻辑进行模块化封装的AOP概念实体。

    通常情况下,Aspect可以包含多个Pointcut以及相关Advice定义。

5) Weaver。

    Weaver是织入器,职责是完成横切关注点逻辑到系统的最终织入。

    ProxyFactory类是Spring AOP中最通用的织入器。

6) Target。

    符合Pointcut指定的条件,将被织入横切逻辑的对象。

7) AOP各个概念所处的场景。

3.2 实践

【强制】动态代理。

1) 代理模式。

    提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来,即解耦。

2) 动态代理代码示例。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;public class Test {public static void main(String[] args) {ProxyFactory factory = new ProxyFactory(new MyInterfaceImpl());MyInterface proxy = (MyInterface) factory.getProxy();proxy.hello("myParam");}
}interface MyInterface {String hello(String s);
}class MyInterfaceImpl implements MyInterface {@Overridepublic String hello(String s) {return "hello world";}
}class ProxyFactory {private Object target;public ProxyFactory(Object target) {this.target = target;}public Object getProxy() {ClassLoader classLoader = target.getClass().getClassLoader();Class<?>[] interfaces = target.getClass().getInterfaces();InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;try {System.out.println("[动态代理][日志] 方法名: " + method.getName());System.out.println("[动态代理][日志] 参数列表:" + Arrays.toString(args));System.out.println("[动态代理][日志] 开始执行");result = method.invoke(target, args);System.out.println("[动态代理][日志] 返回值:" + result);} catch (Exception e) {System.out.println("[动态代理][日志] 异常:" + e.getMessage());} finally {System.out.println("[动态代理][日志] 执行完毕");}return result;}};return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);}
}

【强制】Pointcut表达式。

1) 匹配模式。

    execution、within、this、target、args等。

2) execution模式表达式格式。

    execution([权限修饰符] [返回类型] [全类名].[方法名]([参数列表]))

    权限修饰符、返回类型、全类名、方法名 可以用通配符 * 代替。

    全类名、方法名可以部分匹配,如*Service、get*。

    参数列表 可以用 .. 代替。

【强制】@AspectJ 形式的Advice。

1) @Before。

2) @AfterReturning。

3) @AfterThrowing。

4) @After。

5) @Around。

【推荐】@AspectJ 形式的Spring AOP。

1) 配置文件bean.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 开启组件扫描 --><context:component-scan base-package="com.mypath"></context:component-scan><!-- 开启aop自动代理 --><bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><property name="proxyTargetClass" value="true"></property></bean><!-- 基于Schema的aop自动代理 --><!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->
</beans>

2) Java代码。

package com.mypath;import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;public class Test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");MyTask proxy = (MyTask) context.getBean("myTask");proxy.task1();proxy.tas k2();}
}@Component
class MyTask {public void task1() {System.out.println("task1 执行");}public void task2() {System.out.println("task2 执行");}
}@Aspect
@Component
class PerformanceTraceAspect {private final Logger logger = Logger.getLogger(PerformanceTraceAspect.class);@Pointcut("execution(public void com.mypath.MyTask.task1()) || execution(public void com.mypath.MyTask.task2())")public void pointcut() {}@Around("pointcut()")public Object performanceTrace(ProceedingJoinPoint joinPoint) throws Throwable {String methodName = joinPoint.getSignature().getName();try {logger.info(methodName + " 开始执行");return joinPoint.proceed();} finally {logger.info(methodName + " 执行结束");}}
}

3) 输出。

[02-13 12:42:20] [INFO] [com.mypath.MyAspect:45] task1 开始执行
task1 执行
[02-13 12:42:20] [INFO] [com.mypath.MyAspect:48] task1 执行结束
[02-13 12:42:20] [INFO] [com.mypath.MyAspect:45] task2 开始执行
task2 执行
[02-13 12:42:20] [INFO] [com.mypath.MyAspect:48] task2 执行结束

【推荐】基于Schema的Spring AOP。

1) Java代码。

package com.mypath;import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;public class Test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");MyTask myTask = (MyTask) context.getBean("myTask");myTask.task();}
}@Component
class MyTask {public void task() {System.out.println("task 执行");}
}@Component
class MyAspect {private final Logger logger = Logger.getLogger(MyAspect.class);public void doBefore(JoinPoint joinPoint) {if (logger.isInfoEnabled()) {logger.info("before method[" + joinPoint.getSignature().getName() + "] execution.");}}public void doAfterReturning(JoinPoint joinPoint) {if (logger.isInfoEnabled()) {logger.info("method[" + joinPoint.getSignature().getName() + "] completed successfully.");}}public void doAfterThrowing(RuntimeException e) {logger.error(ExceptionUtils.getFullStackTrace(e));}public void doAfter() {logger.warn("release system resources, etc.");}public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {StopWatch watch = new StopWatch();try {watch.start();return joinPoint.proceed();} finally {watch.stop();if (logger.isInfoEnabled()) {logger.info(watch);}}}
}

2) 配置文件bean.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 开启组件扫描 --><context:component-scan base-package="com.mypath"></context:component-scan><!-- aop配置 --><aop:config><aop:aspect id="myAspect" ref="myAspect" order="2"><aop:pointcut id="privatePointcut" expression="execution(public void com.mypath.MyTask.task())"/><aop:before pointcut-ref="privatePointcut" method="doBefore"/><aop:after-returning pointcut-ref="privatePointcut" method="doAfterReturning"/><aop:after-throwing pointcut-ref="privatePointcut" method="doAfterThrowing" throwing="e"/><aop:after pointcut-ref="privatePointcut" method="doAfter"/><aop:around pointcut-ref="privatePointcut" method="doAround"/></aop:aspect></aop:config>
</beans>

3) 输出。

[02-13 13:22:40] [INFO] [com.mypath.MyAspect:33] before method[task] execution.
task 执行
[02-13 13:22:40] [INFO] [com.mypath.MyAspect:60] StopWatch '': running time = 11056500 ns; [] took 11056500 ns = 100%
[02-13 13:22:40] [WARN] [com.mypath.MyAspect:49] release system resources, etc.
[02-13 13:22:40] [INFO] [com.mypath.MyAspect:40] method[task] completed successfully.

4 事务

【推荐】声明式事务。

事务控制的代码结构基本是确定的,所以框架就可以将固定模式的代码抽取出来,进行封装。

通过配置的方式、由框架实现的事务称为声明式事务。

【推荐】Spring事务属性。

1) 只读。

    true/false。

2) 超时。

    超时回滚。单位:秒。

3) 回滚策略。

    rollbackFor:回滚。

    noRollbackFor:不回滚。

4) 隔离级别。

    DEFAULT:使用数据库默认的隔离级别。

    READ_UNCOMMITTED:读未提交。

    READ_COMMITTED:读已提交。

    REPEATABLE_READ:可重复读。

    SERIALIZABLE:串行化。

5) 传播行为。

    REQUIRED:支持当前事务,如果当前没有事务,就新建一个(默认)。

    SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式运行。

    MANDATORY:如果当前没有事务,抛出异常。

    REQUIRES_NEW:开启一个新的事务,如果有已存在的事务,将已存在的事务挂起。

    NOT_SUPPORTED:以非事务方式运行,如果有已存在的事务,将已存在的事务挂起。

    NEVER:以非事务方式运行,如果有已存在的事务,抛出异常。

    NESTED:如果有已存在的事务,则运行在一个嵌套式事务中。被嵌套的事务可以独立于外层事务进行提交或回滚。

【推荐】事务的全注解实现。

1) 配置事务。

import javax.sql.DataSource;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@ComponentScan("com.mypath")
@EnableTransactionManagement
public class Test {@Beanpublic DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}

2) 使用事务。

使用@Transactional 注解标识类或方法。

5 统一资源加载

开发中。。

6 其他

6.1 反射

【推荐】反射。

1) 获取Class对象。

Class clazz1 = MyClass.class;
Class clazz2 = new MyClass().getClass();
Class clazz3 = Class.forName("com.mypath")

2) 获取构造方法。

// 获取所有的构造方法
Constructor[] constructors1 = clazz2.getDeclaredConstructors();
// 获取所有的public构造方法
Constructor[] constructors2 = clazz2.getConstructors();// 带参数的构造方法, 括号内为参数对应的Class对象列表
Constructor constructor = clazz2.getConsturctor(String.class, int.class);

3) MyClass实例化。

// 如果constructor为private构造方法
// constructor.setAccessible(true);
MyClass myClass = (MyClass)constructor.newInstance("param1", 2);

4) 获取属性。

// 获取所有的属性
Field[] fields1 = clazz1.getDeclaredFields();
// 获取所有的public属性
Field[] fields2 = clazz1.getFields();

5) 获取方法。

// 获取所有的方法
Method[] methods1 = clazz2.getDeclaredMethods();
// 获取所有的public方法
Method[] methods2 = clazz2.getMethods();

6) 执行方法。

// 如果method为private方法
// method.setAccessible(true);
method.invoke("param1", 2);

6.2 Log4j2

【推荐】Log4j2的重要组件。

1) 日志信息的优先级。

    日志信息的优先级从低到高有:TRACE(追踪)、DEBUG(调试)、INFO(信息)、WARN(警告)、FATAL(严重错误)。

2) 日志信息的输出目的地。

    将日志打到控制台或文件。

3) 日志信息的输出格式。

【推荐】log4j2的使用。

1) 引入依赖。

<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version>
</dependency>

2) 创建配置文件log4j2.xml。

    省略。

3) 导包。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

4) 初始化Logger对象。

private Logger logger = LoggerFactory.getLogger(MyClass.class);

5) 打印信息。

logger.info("hello world");

6.3 JdbcTemplate

【推荐】JdbcTemplate的使用。

1) 引入依赖。

<!-- Spring JDBC -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.0.2</version>
</dependency>
<!-- Druid数据源 -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.15</version>
</dependency>
<!-- MySQL驱动 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>

2) 创建配置文件jdbc.properties。

jdbc.user=roo
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&useSSL=false
jdbc.driver=com.mysql.cj.jdbc.Driver

3) 创建配置文件bean.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 导入外部属性文件 --><context:property-placeholder location="classpath:jdbc.properties"/><!-- 配置JDBCTemplate --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="druidDataSource"/></bean><!-- 配置数据源 --><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="${jdbc.url}"/><property name="driverClassName" value="${jdbc.driver}"/><property name="username" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></bean>
</beans>

4) 创建测试类。

import java.util.List;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;public class Test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");String insertSql = "INSERT INTO my_table VALUES(?, ?, ?)";Object[] params = { 1, "hello", "world" };jdbcTemplate.update(insertSql, params);String selectSql = "SELECT * FROM my_table";List<Object> list = jdbcTemplate.query(selectSql,new BeanPropertyRowMapper<>(Object.class));System.out.println(list);}
}

【推荐】JdbcTemplate的全注解实现。

import javax.sql.DataSource;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;import com.alibaba.druid.pool.DruidDataSource;@Configuration
@ComponentScan("com.mypath")
public class MySpringConfig {@Bean(name = "jdbcTemplate")public JdbcTemplate getJdbcTemplate(DataSource dataSource) {JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}@Beanpublic DataSource getDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&useSSL=false");return dataSource;}
}

相关文章:

速通Spring

尚硅谷2023最新版Spring6课程_bilibili 1 Spring 【强制】Spring是什么&#xff1f; 1) Spring是一款主流的Java EE轻量级开源框架。 轻量级&#xff1a;体积很小&#xff0c;且不需要依赖于其他组件。 2) 狭义的Spring。 Spring Framework。 3) 广义的Spring。 以Spring F…...

【C++】C++入门

一、 C关键字&#xff08;C98&#xff09; C有63个关键字&#xff08;C语言有32个&#xff09;&#xff0c;如下&#xff1a; asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutabl…...

Linux网络技术学习(五)—— 网络设备初始化(I)

文章目录什么时候进行的设备初始化&#xff1f;设备注册和初始化NIC&#xff08;网卡 Network Interface Card&#xff09;初始化的基本目标设备与内核之间的交互硬件中断中断类型传送节流方式为了改善效率中断共享IRQ处理函数映射的组织irqaction结构体存储方式什么时候进行的…...

[技术选型] ClickHouse和StarRocks的介绍

文章目录1.ClickHouse介绍2.StarRocks介绍1.ClickHouse介绍 ClickHouse是面向联机分析处理&#xff08;OLAP&#xff09;的开源分析引擎。最初由俄罗斯第一搜索引擎Yandex开发&#xff0c;于2016年开源&#xff0c;开发语言为C。由于其优良的查询性能&#xff0c;PB级的数据规…...

算法刷题打卡第90天:表现良好的最长时间段

表现良好的最长时间段 难度&#xff1a;中等 给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这…...

Python语言零基础入门教程(十七)

Python 文件I/O 本章只讲述所有基本的 I/O 函数&#xff0c;更多函数请参考Python标准文档。 #### 打印到屏幕 最简单的输出方法是用print语句&#xff0c;你可以给它传递零个或多个用逗号隔开的表达式。此函数把你传递的表达式转换成一个字符串表达式&#xff0c;并将结果写…...

C语言中大小端问题

目录 一、什么是大小端 二、 举个例子 三、大小端演示 四、解释"二"中举例的问题 ​五、怎么判断是大端还是小端 六、一个题目 一、什么是大小端 大端模式&#xff08;大端字节序存储&#xff09;&#xff1a;就是高位字节数据存放在内存的低地址端&#xff…...

vue2+微前端qiankun从搭建到部署的实践(主子应用切换;集成vue3+vite3子应用)

一、最终效果 二、微前端&#xff08;qiankun&#xff09;介绍及为什么选择用微前端&#xff0c;可以看官网 三、目录结构如下 四、具体配置 一、主应用配置 1、主应用技术栈 Vue-cli4搭建项目Vue2Element-Uiqiankun&#xff1b;Vue2Element-Uiqiankun 2、搭建好主项目&…...

怎么代理微信小程序创业?

随着微信的兴起&#xff0c;小程序已经成为了人们生活中不可或缺的一部分。如果你想要创业的话&#xff0c;那么代理微信小程序是一个不错的选择。本文将为大家介绍怎么代理微信小程序创业。 一、什么是微信小程序 微信小程序是一款专为移动设备使用者而设计的应用。它通过扫…...

今天是情人节呐,我利用Python制作了好多表白的东西,快来吧~

今天是情人节那&#xff0c;有没有现在没有对象的宝子&#xff0c;评论里扣个111哈哈 目录 玫瑰 爱心树 丘比特 多彩气球 阿玥的小课堂 一、情人节的由来 二、情人节的来历和意义 玫瑰 局部代码实现如下&#xff1a; # 花瓣1 turtle.left(150) turtle.circle(-90, 70) …...

【Linux】-- 进程信号(处理、内核)

上篇&#xff1a;【Linux】-- 进程信号&#xff08;认识、应用&#xff09;_川入的博客-CSDN博客 目录 信号其他相关常见概念 pending handler block 信号处理的过程 sigset_t sigset_t使用 系统接口 sigpending sigprocmask 捕捉方法 sigaction struct sigactio …...

C/【静态通讯录】

&#x1f331;博客主页&#xff1a;大寄一场. &#x1f331;系列专栏&#xff1a;C语言学习笔记 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 前言 往期回顾&#xff1a; C/扫雷 C/N子棋 通讯录作为通讯录地址的书本&#xff0c;当今的通讯录可以涵盖多项…...

万卷书 - 让孩子对自己负责 [The Self-Driven Child]

让孩子对自己负责 The Self-Driven Child - 让你的孩子更加科学合理的掌控自己的生活 简介 《The Self-Driven Child》(2018)解释了我们对孩子的习惯性控制欲,它导致了孩子压力过大、难以合作,以及主观能动性差。本书不提倡这种做法,而是认为我们应该帮助孩子自己做出合适…...

Postman中cookie的操作

在接口测试中&#xff0c;某些接口的调用&#xff0c;需要带入已有Cookie&#xff0c;比如有些接口需要登陆后才能访问。 Postman接口请求使用Cookie有如下两种方式&#xff1a; 1、直接在头域中添加Cookie头域&#xff0c;适用于已经知道请求所用Cookie数据的情况。 2、使用…...

torch.grid_sample

参考&#xff1a; 双线性插值的理论Pytorch grid_sample解析PyTorch中grid_sample的使用方法pytorch中的grid_sample()使用 查阅官方文档&#xff0c;TORCH.NN.FUNCTIONAL.GRID_SAMPLE grid_sample的函数签名如下所示&#xff0c;torch.nn.functional.grid_sample(input, gr…...

前端基于 Docker 的 SSR 持续开发集成环境实践

项目收益 整体开发效率提升20%。加快首屏渲染速度&#xff0c;减少白屏时间&#xff0c;弱网环境下页面打开速度提升40%。 权衡 在选择使用SSR之前&#xff0c;需要考虑以下事项&#xff01; SSR需要可以运行Node.js的服务器&#xff0c;学习成本相对较高。对于服务器而言&a…...

ARM交叉编译入门及交叉编译第三方库常见问题解析

1. 交叉编译是什么&#xff1f; 交叉编译简单说来&#xff0c;就是编译成果物的地儿不是你运行这个成果物的地儿。最常见的场景&#xff0c;就是我们要编译一个 ARM版本 的可执行程序&#xff0c;但我们编译这个 ARM版本 可执行程序的地方&#xff0c;是在一个 x86_x64 的平台…...

Ruby Web Service 应用 - SOAP4R

什么是 SOAP&#xff1f; 简单对象访问协议(SOAP,全写为Simple Object Access Protocol)是交换数据的一种协议规范。 SOAP 是一种简单的基于 XML 的协议&#xff0c;它使应用程序通过 HTTP 来交换信息。 简单对象访问协议是交换数据的一种协议规范&#xff0c;是一种轻量的、…...

HashMap底层实现原理概述

原文https://blog.csdn.net/fedorafrog/article/details/115478407 hashMap结构 常见问题 在理解了HashMap的整体架构的基础上&#xff0c;我们可以试着回答一下下面的几个问题&#xff0c;如果对其中的某几个问题还有疑惑&#xff0c;那就说明我们还需要深入代码&#xff0c…...

Linux驱动学习环境搭建

背景常识 一、程序分类 程序按其运行环境分为&#xff1a; 1. 裸机程序&#xff1a;直接运行在对应硬件上的程序 2. 应用程序&#xff1a;只能运行在对应操作系统上的程序 二、计算机系统的层次结构 所有智能设备其实都是计算机&#xff0c;机顶盒、路由器、冰箱、洗衣机、汽…...

Java基础之异常

目录1 异常1.1 异常的概述1.2 常见异常类型1.3 JVM的默认处理方案1.4 编译时异常的处理方式1.4.1 异常处理之 try ... catch ... [ktʃ]&#xff08;捕获异常&#xff09;1.4.2 异常处理之 throws&#xff08;抛出异常&#xff09;1.5 Throwable 的成员方法1.6 编译时异常和运行…...

感慨:大三了,未来该何去何从呢

笔者曾在十一月份通过了字节跳动的三次面试&#xff0c; 但是最终因为疫情原因不能满足公司的入职时间要求&#xff0c; 没有拿到offer。近期也是投递了大量大厂的实习岗&#xff0c; 但是要么已读不回&#xff0c; 要么明确告诉我学历至少要985硕士(天天被阿里cpu)。 说实话一…...

分账系统逻辑

一、说明 主体与业务关系方进行相关利益和支出的分配过程 使用场景&#xff1a; 在分销业务中&#xff0c;主营商户收到用户购买分销商品所支付的款项后&#xff0c;可以通过分账逻辑&#xff0c;与分销商进行佣金结算。在零售、餐饮等行业中&#xff0c;当销售人员完零售等…...

SpringCloud篇——什么是SpringCloud、有什么优缺点、学习顺序是什么

文章目录一、首先看官方解释二、Spring Cloud 的项目的位置三、Spring Cloud的子项目四、Spring Cloud 现状五、spring cloud 优缺点六、Spring Cloud 和 Dubbo 对比七、Spring Cloud 学习路线一、首先看官方解释 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式…...

TCP核心机制之连接管理详解(三次握手,四次挥手)

目录 前言&#xff1a; 建立连接 建立连接主要两个TCP状态&#xff1a; 断开连接 断开连接的两个重要状态 小结&#xff1a; 前言&#xff1a; TCP是如何建立对端连接&#xff0c;如何断开连接&#xff0c;这篇文章会详细介绍。 建立连接 首先明确连接的概念&#xff1a…...

前端—环境配置

前端开发建议用 Google Chrome 浏览器 vscode https://code.visualstudio.com 1、open in browser 插件&#xff1a;可以在 vscode 中直接运行查看浏览器效果 2、Live Server 插件&#xff1a;可以使代码修改浏览器页面实时刷新。 用户代码片段 … JavaScript 与 TypeScri…...

大学生常用python变量和简单的数据类型、可迭代对象、for循环的3用法

文章目录变量和简单的数据类型下划线开头的对象删除内存中的对象列表与元组debug三酷猫钓鱼记录实际POS机小条打印使用循环找乌龟可迭代对象&#x1f4d7;理解一&#x1f4d8;理解二2️⃣什么是迭代器✔️注意3️⃣迭代器对象4️⃣有关迭代的函数for循环的3用法&#x1f338;I …...

Java集合:Map的使用

1.Map框架l----Map:双列数据&#xff0c;存储key-value对的数据 ---类似于高中的函数: y f(x)|----HashMap:作为Map的主要实现类&#xff0c; 线程不安全的&#xff0c;效率高&#xff1b;可以存储null的key和value|----LinkedHashMap:保证在遍历map元素时&#xff0c;可以按照…...

【Datawhale图机器学习】第一章图机器学习导论

图机器学习导论 学习路径与必读论文清单 斯坦福CS224W&#xff08;子豪兄中文精讲&#xff09;知识图谱实战DeepwalkNode2vecPageRankGNNGCNGragh-SAGEGINGATTrans-ETrans-R 图无处不在 图是描述关联数据的通用语言 举例 计算机网络新冠肺炎流行病学调查传播链食物链地铁图…...

window 配置深度学习环境GPU

CUDA 11.6 CUDNN Anaconda pytorch 参考网址&#xff1a;https://zhuanlan.zhihu.com/p/460806048 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 电脑信息 RTX 2060 GPU0 1. CUDA 11.6 1.1 确认信息 C:\Users\thzn>nvidia-smi &#xff08;CUDA Versi…...

广安企业网站建设/竞价sem托管

Python入门教程&#xff1a;内置函数 — Map、Reduce、Filter 1. map 根据提供的函数对指定序列做映射,第一个参数function以参数序列中的每一个元素调用function函数&#xff0c;返回包含每次function函数返回值的迭代器 map(function, iterable, ...)function&#xff1a;…...

微分销平台登录/上海怎么做seo推广

一、概述 当父类知道子类应该包含什么样的方法&#xff0c;但无法确定子类如何实现这些方法&#xff1b;在分析事物时&#xff0c;会发现事物的共性&#xff0c;将共性抽取出&#xff0c;实现的时候&#xff0c;就会有这样的情况&#xff1a;方法功能声明相同&#xff0c;但方…...

企业内部网站模板/百度推广网站平台

在梅耶尔担任CEO期间&#xff0c;雅虎摇身一变成为了“收购狂”。这家公司在2014年4月前收购了近40家初创公司&#xff0c;然而非常不幸的是&#xff0c;这些初创公司的产品或服务大多难逃一死。这也让业界将雅虎戏称为“初创企业杀手”。 在梅耶尔看来&#xff0c;从初创企业获…...

南京有哪些知名的网站建设/湖南平台网站建设制作

当我们使用adb命令操作手机的时候经常会报错这个错误一般是adb的端口&#xff08;5037&#xff09;被占用&#xff0c;造成adb server无法启动&#xff0c;解决问题的思路就是查看是哪个程序占用了adb调试端口&#xff0c;然后结束掉它就行。查找哪个进程占用了5037端口netstat…...

网站开发后台能用c语言吗/北京网络推广有哪些公司

一、 需求&#xff1a;1、爬取豆瓣电影top250. 2、获取电影名称,排名,分数,简介,导演,演员。 3、将爬取到的数据保存&#xff0c;以便随时查看。 3、可以将获取到的数据展示给用户。 二、 参考&#xff1a; 豆瓣api参考资料 小试牛刀--利用豆瓣API爬取豆瓣电影top250 三、   …...

北京网站域名备案/建设网站的基本流程

python爬虫scrapy基本使用超详细教程 http://www.guikeyun.com/cms/news/352587.html 一、介绍 官方文档&#xff1a;中文2.3版本 下面这张图大家应该很熟悉&#xff0c;很多有关scrapy框架的介绍中都会出现这张图&#xff0c;感兴趣的再去查询相关资料&#xff0c;当然学会…...