Spring5查缺补漏

Spring5-基础知识

笔记简介:

1、Spring概念

2、IOC

3、AOP

4、JDBCTemplate

5、事务管理

6、Spring5里边的新特性

概述:

1、Spring框架是一个轻量级 开源的javaEE框架。

轻量级:引入依赖的jar包数量少,体积小。不再需要依赖其他的组件,可以单独使用。

(1)IOC:控制反转。不再new对象,而是把创建对象的过程交给Spring,进行管理。

(2)AOP:面向切面编程。不再修改源代码进行功能的修改增强。

特点:

1、方便解耦,简化开发

2、AOP编程支持

3、方便程序的测试,整合Junit

4、方便集成各种框架

5、支持事务的管理

6、源码经典

入门案例-Spring创建对象

下载Spring5的jar包

5.2.6GA稳定版本 https://repo.spring.io

https://repo.spring.io/ui/native/plugins-release/org/springframework/spring/5.2.0.M3/

1、准备5个jar包

commons-logging-1.1.1.jar
spring-beans-5.2.0.M3.jar
spring-context-5.2.0.M3.jar
spring-core-5.2.0.M3.jar
spring-expression-5.2.0.M3.jar

2、测试代码

<?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">

    <!-- 配置User类的对象的创建 -->
    <bean id="user" class="com.pshdhx.User"></bean>
</beans>
package com.pshdhx;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Auther: pshdhx
 * @Date: 2023/08/24/14:50
 * @Description:
 */
public class TestDemo {
    @Test
    public void testAdd(){
        /**
         * 1、加载spring的配置文件
         * 2、获取配置的对象
         */
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user",User.class);
        System.out.println("user = " + user);
        user.add();
    }
}

IOC容器

底层原理

​ 1、控制反转:把对象创建和对象之前的调用过程,交给Spring进行管理。

​ 2、降低耦合度

​ 主要用到了xml的解析、工厂设计模式、反射。

工厂模式:两个类之前的调用,多了一个工厂类

class UserFactory{
	public static UserDao getDao(){
		return new UserDao();
	}
}

IOC过程:

1、xml配置文件,配置要创建的对象

<bean id="userDao" class="com.pshdhx.UserDao"></bean>

2、工厂类

class UserFactory{
	public static UserDao getDao(){
		String classValue = class属性值; //xml解析
		Class clazz = Class.forName(classValue);// 通过反射创建对象        
        return (UserDao)clazz.newInstance(); 	
	}
}

降低耦合度:比如说UserDao的路径改变了,用之前的方式,需要都要改,用现在的方式,只需要改配置文件即可。

BeanFactory接口:内部使用接口,不提供开发人员使用。加载配置文件的时候,不会创建对象。在使用的时候,采取创建对象。

ApplicationContext接口:BeanFactory的子接口,功能更强大,一般面向开发人员使用。在加载配置文件的时候,就会创建配置的对象。

ApplicationContext的实现类:

在这里插入图片描述

FileSystem是盘符路径

classPath是工程路径

IOC的Bean管理

1、spring创建对象

2、spring注入属性【==get set方法】

IOC接口 BeanFactory

IOC的bean管理的具体操作,基于xml

创建对象的时候,默认也是执行无参构造方法,完成对象的创建。如果User对象中是有参构造,那么Spring创建对象报错。

DI:依赖注入。

1、使用set方法注入

public class User {
    private String username;

    public void setUsername(String username) {
        this.username = username;
    }

    public void add(){
        System.out.println("this.username=="+this.username);
    }
}
<!-- 配置User类的对象的创建 -->
<bean id="user" class="com.pshdhx.User">
    <property name="username" value="pansd"/>
</bean>

2、使用构造方法注入

public class User {
    private String username;

    public void setUsername(String username) {
        this.username = username;
    }

    public User(String username) {
        this.username = username;
    }

    public void add(){
        System.out.println("this.username=="+this.username);
    }
}
    <!-- 配置User类的对象的创建 -->
    <bean id="user" class="com.pshdhx.User">
<!--        <property name="username" value="pansd"/>-->
        <constructor-arg name="username" value="pshdhx"></constructor-arg>
    </bean>

P空间注入

xmlns:p="http://www.springframework.org/schema/p"
    <bean id="user" class="com.pshdhx.User" p:username="pshdhx">
<!--        <property name="username" value="pansd"/>-->
<!--        <constructor-arg name="username" value="pshdhx"></constructor-arg>-->
    </bean>

注入其他类型

<property name="username">
    <null/>
</property>

<property name="username">
    <value> 
    	<![CDATA[<<pshdhx>>]]
    </value>
</property>

注入外部Bean

<bean id="addressImpl" class="com.pshdhx.Address"></bean>
<bean id="user" class="com.pshdhx.User" >
        <property name="address" ref="addressImpl"/>
</bean>
public class User {
    private Address address;

    public void setAddress(Address address) {
        this.address = address;
    }
}

注入内部bean和级联赋值

1、一对多关系【部门和员工】

<bean id="emp" class="com.pshdhx.Emp">
    <property name="ename" value="pshdhx"/>
    <property name="gender" value="male"/>
    <property name="dept">
        <bean id="dept" class="com.pshdhx.Dept">
            <property name="dname" value="IT"/>
        </bean>
    </property>
</bean>

注入集合:Arr、List、Set、Map

<bean id="student" class="com.pshdhx.Student">
    <property name="courses">
        <array>
            <value>java</value>
            <value>DB</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>list1</value>
            <value>list2</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>set1</value>
            <value>set2</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="key1" value="value1"></entry>
            <entry key="key2" value="value2"></entry>
        </map>
    </property>
</bean>

集合对象为对象

 <property name="courseList">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
  <bean id="course1" class="com.pshdhx.Course">
        <property name="cname" value="Spring5"></property>
    </bean>
    <bean id="course2" class="com.pshdhx.Course">
        <property name="cname" value="SpringMVC"></property>
    </bean>

抽取公用xml:引入名称空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       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
                           http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd">
    
        <util:list id="bookList">
        <value>Spring</value>
        <value>SpringMVC</value>
    </util:list>

    <bean id="book" class="com.pshdhx.Book">
        <property name="bookListString" ref="bookList">
        </property>
    </bean>

IOC的bean管理的具体操作

Spring里边有普通的Bean,还有另外一种Bean-FactoryBean

普通Bean特点:在xml中class定义的是什么类型,那么getBean返回的就是什么类型。

工厂Bean特点:定义类型和返回类型可以不一致。

package com.pshdhx.factoryBean;

import com.pshdhx.Course;
import org.springframework.beans.factory.FactoryBean;

/**
 * @Auther: pshdhx
 * @Date: 2023/08/28/13:27
 * @Description:
 */
public class MyBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        Course course = new Course();
        course.setCname("Java");
        return course;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}
@Test
public void testMyBean(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    Course myBean = context.getBean("myBean", Course.class);
    System.out.println("myBean = " + myBean);
}

Bean的作用域

作用域:是单实例还是多实例,默认是单实例的。

getBean两次,看看对象是否是单实例。

bean标签行中,有个scope属性设置:singleton/prototype

特点:

singleton:单实例。加载spring配置文件的时候,创建单实例对象。

prototype:多实例。不是在加载Spring配置文件的时候创建对象,而是在getBean的时候,创建新的对象。

request:一次请求

session:一次会话

bean的生命周期

生命周期:从对象的创建到对象的销毁。

1、通过构造器创建Bean实例。(无参构造)

2、为Bean的属性值设置值和对其他Bean的引用(调用set方法的过程)。

​ 将Bean的实例,传递给后置处理器的方法【初始化之前】

3、调用Bean里边的初始化的方法(需要进行配置)

​ 将Bean的实例,传递给后置处理器的方法【初始化之后】

4、bean可以使用了,对象可以获取到了

5、当容器在关闭的时候,bean调用销毁的方法(需要进行配置)。

代码演示:

public class BeanInit {
    private String initName;

    public BeanInit() {
        System.out.println("第一步:无参构造");
    }

    public void setInitName(String initName) {
        this.initName = initName;
        System.out.println("第二步:set设置属性值");
    }

    public void initMethod(){
        System.out.println("第三步:Bean初始化方法");
    }
    public void destoryMethod(){
        System.out.println("第五步:Bean销毁方法");
    }
}
@Test
public void testMyBean(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    BeanInit beanInit = context.getBean("beanInit", BeanInit.class);
    System.out.println("第四步:获取对象"+beanInit);
    context.close();
}

结果:

在这里插入图片描述

这个初始化的前置和后置方法,并没有和某一个bean做关联,所以说每个Bean的初始化之前和之后,都是会执行这个方法的。

public class BeforeAfterBeanInit implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行初始化方法之前");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行初始化方法之后");
        return bean;
    }
}

Bean管理-基于xml的自动装配

手动装配:bean标签中的

自动装配:根据指定的装配规则(属性类型和属性名称),spring会自动帮助我们完成注入。

演示自动装配过程:

Bean的id的值和类名必须一致。

byType:相同类型的Bean只能注册一个。

Bean管理-引入外部的属性文件

引入:druid.jar的包

引入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:property-placeholder location="classpath:jdbc.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
        <property name="url" value="${db.url}"/>
        <property name="driverClassName" value="${db.driverClassName}"/>
    </bean>

基于注解实现创建对象和属性注入

注解:代码的特殊标记@注解名称(属性名=属性值,属性名=属性值)

注解:

1、可以在方法中、类中、属性中都可以加注解

2、目的:简化配置

@Component:

@Service:

@Controller

@Repository

(1) 需要额外引入aop的依赖。

(2)开启组件扫描 引入context

<context:component-scan base-package="com.pshdhx.annotation" ></context:component-scan>

(3)创建类,加注解

@Component
public class Bean1 {
    public void test(){
        System.out.println("annotation 创建对象");
    }
}

组件扫描细节:

   <context:component-scan base-package="com.pshdhx.annotation" ></context:component-scan>
    <context:component-scan base-package="com.pshdhx.annotation"  use-default-filters="false">
        <!-- 只扫描带Controller注解的类 -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <context:component-scan base-package="com.pshdhx.annotation" >
        <!-- 不扫描带Controller注解的类 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>

基于注解实现属性注入

1、@Autowired:根据属性类型注入

2、@Qualifier:根据属性名称自动注入,配合autowired一块使用

3、@Resource:根据类型和名称进行注入

4、@Value

@Value(value="pshdhx")
private String name;

纯注解开发

//1、创建配置类、替代xml文件
@Configuration
@ComponentScan(basePackages={"com.pshdhx"})
public class SpringConfig{
	
}
//编写测试类,不再加载xml文件了
public void test{
	ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
	
}

AOP

概念:对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低,提高程序的可重用性,同时提高开发效率。

AOP的使用场景——登录功能:例如添加权限,if 管理员 if普通用户。

AOP就是在不通过修改源代码的方式添加新的功能。

权限管理模块,独立出一个新的模块,配置到主干里边去。

底层原理:

使用到了动态代理,增强了类中某个方法的功能。

(1)有接口的情况:要使用到JDK的动态代理。

创建出代理对象,通过代理对象实现某些功能。

public class TestAopJdkProxy {
    public static void main(String[] args) {
        //创建UserDao的代理对象,利用这个对象进行功能的修改操作
        UserDao userDao = (UserDao) Proxy.newProxyInstance(TestAopJdkProxy.class.getClassLoader(), new Class[]{UserDao.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println(method.getName() + "方法执行之前,参数是:"+ Arrays.toString(args));
//                        Object proxy 这个是object对象,没有什么东西
                        Object result = method.invoke(new UserDaoImpl(), args);
                        System.out.println("方法执行之后");
                        return result;
                    }
                }
        );
        userDao.add(3, 4);
    }
}

(2)没接口的情况:要使用到CGLIB动态代理。

继承某个类,重写方法。【创建子类的代理对象】

术语

连接点:可以被增强的方法。

切入点:真正被增强的方法。

通知:实际增强的逻辑部分。【前置、后置、环绕、异常、最终通知】

切面:把通知应用到切入点的过程。

AOP操作

使用AspectJ工具实现AOP操作,单独的AOP框架,不是基于Spring的

1、基于注解的配置方式

(1)引入jar包

​ spring-aspects-5.2.0.M3.jar

​ cglib-2.2.jar

​ aspectjweaver-1.6.8.jar

​ aopalliance-1.0.jar

(2)切入点表达式,对哪个类中的哪个方法进行增强

execution([权限修饰符][返回类型][类的全路径][方法名字][参数列表])
execution(* com.pshdhx.aop.TestClass.add(..))
execution(* com.pshdhx.aop.TestClass.*(..))
execution(* com.pshdhx.aop.*.*(..))

after是方法之后执行

afterReturning是返回值返回之后执行

xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
<context:component-scan base-package="com.pshdhx.aop.aspectj"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Component
@Aspect
public class UserProxy {
    @Before(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void before(){
        System.out.println("前置通知。。。。");
    }

    @After(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void after(){
        System.out.println("后置通知。。。。");
    }

    @Around(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void arround(ProceedingJoinPoint p) throws Throwable {
        System.out.println("环绕通知-前置环绕。。。。");
        p.proceed();
        System.out.println("环绕通知-后置环绕。。。。");

    }

    @AfterReturning(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void afterReturning(){
        System.out.println("afterReturning通知。。。。");
    }

    @AfterThrowing(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void afterThrowing(){
        System.out.println("afterThrowing通知。。。。");
    }
}

出现了异常之后,后置环绕通知和afterReturning接收不到。但是,around必须抛出异常,下边才能afterThrowing。

异常顺序:

环绕通知-前置环绕。。。。
前置通知。。。。
后置通知。。。。
afterThrowing通知。。。。

正常顺序:

环绕通知-前置环绕。。。。
前置通知。。。。
User 的add 方法
环绕通知-后置环绕。。。。
后置通知。。。。
afterReturning通知。。。。

切入点的抽取:

@AfterReturning(value = "pointCut()")
    public void afterReturning(){
        System.out.println("afterReturning通知。。。。");
}

@Pointcut(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
public void pointCut(){

}

设置增强类的优先级:

一个方法被多次增强,可以在类上加一个注解@Order(1) 先执行 @Order(2)后执行

2、基于xm的配置方式

<!-- 以下是基于xml -->
<bean id="person" class="com.pshdhx.aop.xml.Person"></bean>
<bean id="personProxy" class="com.pshdhx.aop.xml.PersonProxy"></bean>
<aop:config>
    <aop:pointcut id="p" expression="execution(* com.pshdhx.aop.xml.Person.add(..))"/>

    <aop:aspect ref="personProxy">
        <aop:before method="before" pointcut-ref="p"/>
    </aop:aspect>
</aop:config>

JdbcTemplate

Spring框架对JDBC进行了封装,使用JdbcTemplate方便实现对数据库的操作。

1、引入jar包

druid-1.1.9.jar
mysql-connector-java-5.1.8.jar
spring-jdbc-5.2.0.M3.jar
spring-orm-5.2.0.M3.jar
spring-tx-5.2.0.M3.jar

增删改操作:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
                           http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd
">

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <context:component-scan base-package="com.pshdhx.jdbctemplate"/>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
        <property name="url" value="${db.url}"/>
        <property name="driverClassName" value="${db.driverClassName}"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>


</beans>
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int addUser(User user) {
        String sql = "insert user(user_id,username,user_status) values (?,?,?)";
        Object []args = {user.getUserId(),user.getUserName(),user.getUserStatus()};
        int update = jdbcTemplate.update(sql, args);
        return update;
    }
}

查询操作:某个值count(*),某条记录,多条记录的集合

public int findCount() {
    String sql = "select count(*) from user";
    Integer integer = jdbcTemplate.queryForObject(sql, Integer.class);
    return integer;
}

查询某一条记录

public User findUserById(Integer id) {
    String sql = "select * from user where user_id = ?";
    Object []args = {id};
    User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), args);
    return user;
}

查询多条记录

@Override
public List<User> queryAllUser() {
    List<User> userL = jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<User>(User.class));
    return userL;
}

批量添加:

@Override
public void batchImport(List<Object []> userList) {
    String sql = "insert into user values(?,?,?)";
    jdbcTemplate.batchUpdate(sql,userList);
}

List<Object[]> list = new ArrayList<>();
        Object[] u1 = {12,"12","0"};
        Object[] u2 = {13,"13","1"};
        Object[] u3 = {14,"14","1"};
        list.add(u1);
        list.add(u2);
        list.add(u3);
        userService.batchImport(list);

事务

事务特性:

​ 原子性:要么都成功,要么都失败。

​ 一致性:操作之前和之后,数据一致。

​ 隔离性:多个事务操作,不会产生影响。

​ 持久性:事务提交之后,存库。

声明式事务管理

<!-- 创建事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 开启事务注解
 1、引入名称空间 tx
 2、开启事务注解
 3、在service类中添加注解 @Transactional 可以加到类上边(为类中所有方法添加事务),也可以加到方法上边-->

<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

propagation:事务的传播行为

【一个事务的方法被另外一个事务的方法调用,该如何进行处理?】

1、required传播级别:如果有事务正在运行,当前的方法就在这个事务内运行。否则,就会启动一个新的事务,并在自己的事务内运行。

举例说明:类是事务A,方法是方法1,类是事务B,方法是方法2。方法1调用方法2,方法1会开启事务A,方法2会加入到事务A

2、required_new :当前的方法必须启动新事务,并在它自己的事务内运行。如果有事务正在运行,应该将它挂起。

举例说明:内层事务和外层事务互不影响。

3、supports:如果有事务在运行,当前的方法就在这个事务内运行。否则,它可以不运行在事务中。

举例:【方法A单独的调用方法B,如果方法A没有事务,方法B可以不运行在事务中】

ioslatin:事务的隔离级别

多事务操作之间不会产生影响

脏读:读取到了未提交事务的数据。【不提交可能会回滚】

不可重复读:一个未提交事务,读取到了一个已提交事务修改的数据。
幻读:一个未提交事务,读取到了一个已提交事务添加的数据。

脏读不可重复度幻读
读未提交
读已提交
可重复度[Mysql默认]
串行化
@Service
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.REPEATABLE_READ)
public class UserService{

}

事务的其他参数

1、timeout:事务需要在一定的时间内进行提交。如果不提交,事务需要进行回滚。默认值-1,是不超时的意思。timeout=5,是五秒的意思。

2、readOnly:是否只读。默认值是false【可以查询,可以增删改】,当设置成true之后,只能进行查询操作。

3、rollbackFor:回滚【设置哪些异常可以进行回滚】

4、noRollbackFor:【设置哪些异常不进行异常的回滚】

@Configuration
@ComponentScan(basePackages = "com.pshdhx")
@EnableTransactionManagement
public class TxConfig {

    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("pshdhx");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/user_db");
        return dataSource;
    }

    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource datasource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(datasource);
        return dataSourceTransactionManager;
    }
}

整合日志框架

引入jar包

log4j-core-2.11.2.jar
log4j-slf4j-impl-2.11.2.jar
slf4j-api-1.7.30.jar
log4j-api-2.11.2.jar

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 日志级别以及优先级顺序 OFF >FATAL > ERROR > WARN > INFO > DEBUG >TRACE >ALL -->
<!-- Configuration 后面的status 用于设置log4j2自身内部信息的额输出 可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出 -->
<configuration status="INFO">
    <appenders>
        <console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} -%msg%n"/>
        </console>
    </appenders>

    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>
import com.mysql.jdbc.log.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Auther: pshdhx
 * @Date: 2023/09/09/14:49
 * @Description:
 */
public class UserLogger {

    private static final Logger log = LoggerFactory.getLogger(UserLogger.class);

    public static void main(String[] args) {
        log.info("测试日志");
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值