Spring5学习笔记—高级注解

在这里插入图片描述
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Spring专栏
✨特色专栏: MySQL学习
🥭本文内容:Spring5学习笔记—高级注解
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: 知识库,欢迎大家访问

学习参考 :

  • 讲师:孙帅老师
  • 课程:孙哥说Spring5

1.前言

上一篇博客我们详细介绍了一下有关Spring的基础系列注解,并通过一些案例来讨论使用这些基础注解来简化我们的开发。这篇文章我们将继续讨论Spring高级注解开发,更深入地了解这些强大的工具如何加速开发过程并提高代码质量,好了,话不多说,让我们开始吧😎😎😎。

2.配置Bean

Spring3.x提供的新的注解,用于替换XML配置文件。@Configuration
public class AppConfig{}

开发步骤:

  1. 创建配置类:首先,创建一个Java类,并在其上标记 @Configuration 注解,将其变为一个配置Bean。
  2. 编写配置代码:在配置类中,编写Spring配置代码,包括Bean定义、依赖注入等。
  3. 进行测试:编写测试代码来验证配置类中的配置是否按预期工作。

1.讨论Bean

配置Bean在应用的过程中,替换了XML具体什么内容呢?

image-20200703100033265

2.注解工厂

AnnotationConfigApplicationContext

使用配置Bean之后创建工厂的两种方式:1. 指定配置bean的ClassApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);2. 指定配置bean所在的路径 ApplicationContext ctx = new AnnotationConfigApplicationContext("org.javatop");

3.使用配置Bean的注意事项:

使用配置Bean之后无法再集成log4j日志框架,而应该集成新的日志框架logback

logback集成开发步骤:

3.1 引入相关jar
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version>
</dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>1.7.25</version>
</dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version>
</dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version>
</dependency><dependency><groupId>org.logback-extensions</groupId><artifactId>logback-ext-spring</artifactId><version>0.1.4</version>
</dependency>
3.2 引入logback配置文件

在Resource目录下面创建logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><root level="DEBUG"><appender-ref ref="STDOUT" /></root></configuration>
  • @Configuration注解的本质

    在传统的Spring开发中,我们通常使用XML文件来配置应用程序的组件、依赖关系和其他配置信息。但是,随着应用程序的复杂性增加,XML配置文件变得冗长、繁琐,并且容易出错。为了简化配置,Spring引入了基于Java的配置方式,即通过编写Java类来提供配置信息,这就是配置类。

    @Configuration注解标记的类被称为配置类,它充当了传统XML配置文件的替代品,提供了一种更加直观、类型安全和可维护的配置方式。配置类可以包含一些特殊的注解和方法,用于声明和定义Spring Bean以及其他配置元素。

    那么,@Configuration注解的本质是什么呢?简单来说,@Configuration注解告诉Spring容器,被注解的类是一个配置类,它包含了一些用于配置应用程序的Bean定义和其他配置元素。

    具体来说,当Spring容器扫描到被@Configuration注解标记的类时,它会解析该类,并根据其中的配置信息创建相应的Bean定义。这些配置信息可以包括@Bean注解标记的方法,用于定义Bean的创建和初始化逻辑。同时,配置类还可以使用其他注解,如@ComponentScan@Import等,来进一步定义和引入其他的Bean定义和配置。

    配置类的优势在于它提供了更加灵活、可读性高的配置方式。我们可以在配置类中使用Java语言的特性,如条件判断、循环等,来动态创建和配置Bean。同时,配置类的类型安全性更高,编译器可以帮助我们检测配置错误和类型不匹配的问题。

    总结起来,@Configuration注解的本质是告诉Spring容器,被注解的类是一个配置类,它包含了用于配置应用程序的Bean定义和其他配置元素。通过配置类,我们可以以Java类的形式来定义和管理Spring应用程序的配置信息,提供了更加直观、类型安全和可维护的配置方式。

    也是@Component注解的衍生注解,可以应用<context:component-scan进行扫描。

2. @Bean注解

@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean标签

2.1 @Bean注解的基本使用

1.什么是简单对象什么是复杂对象呢

在Spring中,简单对象和复杂对象是相对的概念,用于描述对象的结构和复杂程度。

简单对象(Simple Object) 通常指的是简单的数据类型或简单的POJO(Plain Old Java Object)。简单数据类型包括基本数据类型**(如整数、浮点数、布尔值等)以及它们的包装类型(如Integer、Float、Boolean等)。简单POJO是指没有复杂业务逻辑和依赖关系的普通Java对象,通常只包含一些简单的属性和对应的gettersetter**方法。

复杂对象(Complex Object)通常指的是具有复杂结构和关联关系的对象。这些对象可能包含嵌套的对象、集合或其他复杂类型的属性。复杂对象可能涉及到多层级的关系,需要进行依赖注入、关联关系的管理和业务逻辑的处理。

在Spring中,对于简单对象,通常可以直接使用基本的依赖注入方式,如通过@Autowired注解注入简单的依赖对象。而对于复杂对象,通常需要进行更复杂的配置和管理,如通过XML配置文件或注解配置相关的依赖关系、使用@Qualifier注解解决依赖对象的歧义性、使用@Autowired注解注入集合类型的属性等。

需要注意的是,简单对象和复杂对象并没有严格的定义和界限,它们的划分主要是为了描述对象的复杂程度和处理方式。在实际开发中,根据具体的业务需求和对象的结构,可以灵活地选择适合的依赖注入方式和配置方式。

简单来说:简单对象就是直接能够通过new方式创建的对象,比如new User()。复杂对象就是不能通过new的方式直接创建的对象。比如 Connection SqlSessionFactory等等

2.简单对象的创建

image-20231022144250397

3.复杂对象的创建
  //@Bean 创建复杂对象//一般用于遗留系统整合 @Beanpublic Connection conn1() {Connection conn = null;try {ConnectionFactoryBean factoryBean = new ConnectionFactoryBean();conn = factoryBean.getObject();} catch (Exception e) {e.printStackTrace();}return conn;}
4.自定义id值
@Bean("id")
5.控制对象创建次数
@Bean
@Scope("singleton|prototype") 默认值 singleton

当我们使用@Scope注解的时候,value值为sinleton时或者不填写@Socope注解时,Spring只会为我们创建一个对象。当我们value值为prototype,此时Spring会为我们创建多个对象。

image-20231022145500394

2.2 @Bean注解的注入

1. 用户自定义类型
//待注入对象
@Bean
public UserDAO userDAO() {return new UserDAOImpl();
}
  //方式一:待注入对象作为参数:@Beanpublic UserService userService(UserDAO userDAO) {UserServiceImpl userService = new UserServiceImpl();userService.setUserDAO(userDAO);return userService;}
//方式二(简化):直接调用该方法:
@Bean
public UserService userService() {UserServiceImpl userService = new UserServiceImpl();userService.setUserDAO(userDAO());return userService;
}
2. JDK类型的注入
@Bean
public Customer customer() {Customer customer = new Customer();customer.setId(1);customer.setName("xiaohei");return customer;
}

JDK类型注入细节分析:如果直接在代码中进行set方法的调用,会存在耦合的问题,怎么解决?

  @Configuration@PropertySource("classpath:/init.properties")public class AppConfig1 {@Value("${id}")private Integer id;@Value("${name}")private String name;@Beanpublic Customer customer() {Customer customer = new Customer();customer.setId(id);customer.setName(name);return customer;}}

3. @ComponentScan注解

@Configuration注解是Spring框架中的一个重要注解,用于标记一个类为配置类。配置类提供了Spring应用程序的配置信息,替代了传统的XML配置文件。在详细解释@Configuration注解的本质之前,我们先了解一下它的背景和作用。

在传统的Spring开发中,我们通常使用XML文件来配置应用程序的组件、依赖关系和其他配置信息。但是,随着应用程序的复杂性增加,XML配置文件变得冗长、繁琐,并且容易出错。为了简化配置,Spring引入了基于Java的配置方式,即通过编写Java类来提供配置信息,这就是配置类。

@Configuration注解标记的类被称为配置类,它充当了传统XML配置文件的替代品,提供了一种更加直观、类型安全和可维护的配置方式。配置类可以包含一些特殊的注解和方法,用于声明和定义Spring Bean以及其他配置元素。

那么,@Configuration注解的本质是什么呢?简单来说,@Configuration注解告诉Spring容器,被注解的类是一个配置类,它包含了一些用于配置应用程序的Bean定义和其他配置元素。

具体来说,当Spring容器扫描到被@Configuration注解标记的类时,它会解析该类,并根据其中的配置信息创建相应的Bean定义。这些配置信息可以包括@Bean注解标记的方法,用于定义Bean的创建和初始化逻辑。同时,配置类还可以使用其他注解,如@ComponentScan@Import等,来进一步定义和引入其他的Bean定义和配置。

配置类的优势在于它提供了更加灵活、可读性高的配置方式。我们可以在配置类中使用Java语言的特性,如条件判断、循环等,来动态创建和配置Bean。同时,配置类的类型安全性更高,编译器可以帮助我们检测配置错误和类型不匹配的问题。

总结起来,@Configuration注解的本质是告诉Spring容器,被注解的类是一个配置类,它包含了用于配置应用程序的Bean定义和其他配置元素。通过配置类,我们可以以Java类的形式来定义和管理Spring应用程序的配置信息,提供了更加直观、类型安全和可维护的配置方式。等同于XML配置文件中的<context:component-scan标签

3.1 基本使用:

//加载配置Bean上:
@Configuration
@ComponentScan(basePackages = "org.javatop.scan")
public class AppConfig2 {}<context:component-scan base-package=""/

3.2 排除、包含的使用:

1.排除过滤:
<context:component-scan base-package="org.javatop"><context:exclude-filter type="assignable" expression="org.javatop.bean.User"/>
</context:component-scan>

替换为:

  @ComponentScan(basePackages = "org.javatop.scan",excludeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value={Service.class}),@ComponentScan.Filter(type= FilterType.ASPECTJ,pattern = "*..User1")})/*type = FilterType.ANNOTATION          value.ASSIGNABLE_TYPE     value.ASPECTJ             pattern   .REGEX               pattern.CUSTOM              value        */
2.包含过滤:
<context:component-scan base-package="org.javatop" use-default-filters="false"><context:include-filter type="" expression=""/>
</context:component-scan>

替换为:

  @ComponentScan(basePackages = "org.javatop.scan",useDefaultFilters = false,includeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value={Service.class})})/*type = FilterType.ANNOTATION          value.ASSIGNABLE_TYPE     value.ASPECTJ             pattern   .REGEX               pattern.CUSTOM              value               */

4. Spring工厂创建对象的方式分析

1. 多种配置方式的应用场景

image-20200706174301418

2. 配置优先级

@Component及其衍生注解 < @Bean < 配置文件bean标签
优先级高的配置会覆盖优先级低配置 @Component
public class User{}@Bean
public User user(){return new User();
}<bean id="user" class="xxx.User"/>配置覆盖条件:id值 保持一致

3. 解决基于注解进行配置的耦合问题

<!-- applicationContext.xml 配置文件中进行覆盖 -->
<bean id="userDAO" class="org.javatop.injection.UserDAOImplNew"/>
12
@Configuration
//@ImportResource("applicationContext.xml")
public class AppConfig4 {@Beanpublic UserDAO userDAO() {return new UserDAOImpl();}
}@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig5{}

5. 整合多个配置信息

为什么会有多个配置信息

拆分多个配置bean的开发,是一种模块化开发的形式,也体现了面向对象各司其职的设计思想

多配置信息整合的方式

- 多个配置Bean的整合
- 配置Bean与@Component相关注解的整合
- 配置Bean与SpringXML配置文件的整合

整合多种配置需要关注那些要点

- 如何使多配置的信息 汇总成一个整体
- 如何实现跨配置的注入

5.1 多个配置Bean的整合

1.base-package进行多个配置Bean的整合

image-20200707170421669

通过 @Import(xxx.class)

把AppConfig1当作主配置Bean,在AppConfig1上添加@Import(Appconfig2.class),完成整合

image-20200707170745814

在工厂创建时,指定多个配置Bean的Class对象 【了解】

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig1.class,AppConfig2.class);

一个问题:如何跨配置进行注入?

@Configuration
@Import(AppConfig2.class)
public class AppConfig1 {//把要跨配置注入的对象作为本配置Bean的属性@Autowiredprivate UserDAO userDAO;@Beanpublic UserService userService() {UserServiceImpl userService = new UserServiceImpl();userService.setUserDAO(userDAO);return userService;}
}@Configuration
public class AppConfig2 {@Beanpublic UserDAO userDAO() {return new UserDAOImpl();}
}

5.2 配置Bean与@Component相关注解的整合

通过 @ComponentScan(basePackages = " ") 注解整合:

@Component(@Repository)
public class UserDAOImpl implements UserDAO{}@Configuration
@ComponentScan("")
public class AppConfig3 {@Autowiredprivate UserDAO userDAO;@Beanpublic UserService userService() {UserServiceImpl userService = new UserServiceImpl();userService.setUserDAO(userDAO);return userService;}
}ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);

5.3 配置Bean与配置文件整合

使用 @ImportResource(“applicationContext.xml”) 注解整合:

//1. 遗留系统的整合 2. 配置覆盖public class UserDAOImpl implements UserDAO{}
<bean id="userDAO" class="org.javatop.injection.UserDAOImpl"/>@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig4 {@Autowiredprivate UserDAO userDAO;@Beanpublic UserService userService() {UserServiceImpl userService = new UserServiceImpl();userService.setUserDAO(userDAO);return userService;}
}ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig4.class);

6. 配置Bean底层实现原理

Spring在配置Bean中加入了@Configuration注解后,底层就会通过Cglib的代理方式,来进行对象相关的配置、处理

image-20200709114200371

在Spring框架中,配置Bean的底层实现原理主要涉及到两个核心概念:Bean定义和Bean工厂。

  1. Bean定义(Bean Definition): Bean定义是描述Bean的元数据,它包含了Bean的类名、属性值、构造函数参数、生命周期回调等信息。在Spring中,每一个被管理的Bean都需要有一个对应的Bean定义。

    在配置Bean时,可以使用不同的方式来定义Bean。以下是一些常见的配置方式:

    • XML配置文件:使用<bean>标签来定义Bean,可以指定Bean的类名、属性值、构造函数参数等。
    • Java注解:使用注解如@Component@Service@Repository@Controller等来标记Bean类,Spring会自动扫描并解析这些注解,将其转化为Bean定义。
    • Java配置类:使用@Configuration注解的类来定义Bean,使用@Bean注解来标记方法,方法的返回值将作为Bean的实例。

    无论是使用XML配置文件、注解还是Java配置类,最终都会将配置信息解析成Bean定义对象。

  2. Bean工厂(Bean Factory): Bean工厂是Spring框架的核心容器,负责管理和创建Bean的实例。它是一个工厂模式的实现,在应用程序启动时,根据Bean定义创建和管理Bean实例。

    在Spring中,使用ApplicationContext接口来表示Bean工厂。ApplicationContext接口是Bean工厂的一个具体实现。它提供了丰富的方法来获取和管理Bean。

    当应用程序启动时,Spring容器会读取配置文件或扫描注解,解析Bean定义并创建对应的Bean实例。在创建Bean实例时,Bean工厂会根据Bean定义中的信息进行以下操作:

    • 实例化Bean:根据Bean定义中指定的类名,使用Java反射机制创建Bean的实例。
    • 属性注入:根据Bean定义中指定的属性值,将对应的值注入到Bean实例中。
    • 依赖注入:根据Bean定义中指定的依赖关系,将依赖的Bean注入到当前Bean实例中。
    • 生命周期管理:根据Bean定义中指定的生命周期回调方法,调用相应的方法来初始化和销毁Bean实例。

    Bean工厂通过使用Bean定义和反射机制,实现了Bean的动态创建和管理。

配置Bean的底层实现原理主要涉及Bean定义和Bean工厂。Bean定义描述了Bean的元数据,包括类名、属性值等信息。Bean工厂负责管理和创建Bean的实例,根据Bean定义动态创建Bean,并进行属性注入、依赖注入和生命周期管理。这种基于Bean定义和工厂模式的实现方式,使得Spring框架具有了灵活性、可扩展性和可维护性。

7. 四维一体的开发思想

7.1 什么是四维一体

四维一体"是指Spring框架的四个核心维度,它们是:依赖注入(Dependency Injection)、面向切面编程(Aspect-Oriented Programming)、控制反转(Inversion of Control)、和自动化模块化(Component-Based Development)。

  1. 依赖注入(Dependency Injection):依赖注入是Spring框架的核心特性之一。它通过将对象之间的依赖关系的创建和管理交给框架来实现解耦和灵活性。在Spring中,我们将依赖关系声明在配置文件中,或者使用注解来自动注入依赖对象。
  2. 面向切面编程(Aspect-Oriented Programming):面向切面编程是一种通过将横切关注点(例如日志记录、事务管理、安全性等)与核心业务逻辑分离的编程方式。Spring框架通过AOP模块提供了对面向切面编程的支持,使开发人员能够更容易地实现横切关注点的功能。
  3. 控制反转(Inversion of Control):控制反转是指将对象的创建和管理交给框架来处理,而不是由开发人员手动实例化对象。在Spring中,控制反转通过IoC容器来实现,它负责管理和创建应用程序中的对象,并在需要时将这些对象注入到其他对象中。
  4. 自动化模块化(Component-Based Development):自动化模块化是指将应用程序划分为独立的、可重用的组件,每个组件都有明确定义的职责和接口。Spring框架鼓励使用组件化的方式进行开发,通过注解、配置文件等方式将这些组件进行管理和组装。

这四个维度相互关联,共同构成了Spring框架的核心理念和功能。它们帮助开发人员实现代码的松耦合、可维护性和可扩展性,提高开发效率和代码质量。

Spring开发一个功能的4种形式,虽然开发方式不同,但是最终效果是一样的。
1. 基于schema
2. 基于特定功能注解
3. 基于原始<bean
4. 基于@Bean注解

7.2 四维一体的开发案例

  1. 依赖注入(Dependency Injection):
public interface UserService {void addUser(User user);
}@Service
public class UserServiceImpl implements UserService {@Overridepublic void addUser(User user) {// 添加用户逻辑}
}@Controller
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/users")public String createUser(User user) {userService.addUser(user);return "redirect:/users";}
}

在上述代码中,我们定义了一个UserService接口和它的实现类UserServiceImpl,同时在UserController中使用@Autowired注解将UserService自动注入。

2.面向切面编程(Aspect-Oriented Programming):

@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.controller.*.*(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("Before method: " + joinPoint.getSignature().getName());}@After("execution(* com.example.controller.*.*(..))")public void logAfter(JoinPoint joinPoint) {System.out.println("After method: " + joinPoint.getSignature().getName());}
}

在上述代码中,我们创建了一个切面类LoggingAspect,使用@Before@After注解定义了在方法执行前后打印日志的逻辑。

3.控制反转(Inversion of Control):

在Spring的配置文件中,我们可以定义Bean的实例化和配置信息。例如,application-context.xml文件:

<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"><bean id="userService" class="com.example.service.UserServiceImpl" /><bean id="userController" class="org.javatop.controller.UserController"><property name="userService" ref="userService" /></bean>
</beans>

在上述配置文件中,我们定义了userServiceuserController的实例化和依赖关系。

4.自动化模块化(Component-Based Development):

@Repository
public class UserRepository {public void saveUser(User user) {// 保存用户到数据库}
}

在上述代码中,我们定义了一个UserRepository类并使用@Repository注解将其标记为仓库组件。

1. <context:property-placehoder
2. @PropertySource  【推荐】
3. <bean id="" class="PropertySourcePlaceholderConfigure"/>
4. @Bean            【推荐】

8.纯注解编程

1. 纯注解版AOP编程

1. 搭建环境
1. 创建配置Bean 
2. 开启注解扫描 @ComponentScan()
2. 开发步骤
1. 原始对象@Service(@Component)public class UserServiceImpl implements UserService{}
2. 创建切面类 (额外功能 切入点 组装切面)@Aspect@Componentpublic class MyAspect {@Around("execution(* login(..))")public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("----aspect log ------");Object ret = joinPoint.proceed();return ret;}}
3. Spring的配置文件中<aop:aspectj-autoproxy />   替换为:@EnableAspectjAutoProxy ---> 加在配置Bean
3. 注解AOP细节分析
1. 代理创建方式的切换 JDK Cglib <aop:aspectj-autoproxy proxy-target-class=true|false />@EnableAspectjAutoProxy(proxyTargetClass)
2. 注意:SpringBoot默认把@EnableAspectjAutoProxy设置好了,以后使用SpringBoot,进行AOP开发时,不需要额外设置。 Spring AOP 代理默认实现 JDK  SpringBOOT AOP 代理默认实现 Cglib 

2. 纯注解版Spring+MyBatis整合

2.1 基础配置 (配置Bean)
1. 连接池<!--连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/Leo?useSSL=false"></property><property name="username" value="root"></property><property name="password" value="root"></property></bean>@Beanpublic DataSource dataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("");dataSource.setUrl();...return dataSource;}2. SqlSessionFactoryBean<!--创建SqlSessionFactory SqlSessionFactoryBean--><bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><property name="typeAliasesPackage" value="org.javatop.entity"></property><property name="mapperLocations"><list><value>classpath:org.javatop.mapper/*Mapper.xml</value></list></property></bean>@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setTypeAliasesPackage("");...return sqlSessionFactoryBean;}3. MapperScannerConfigure <!--创建DAO对象 MapperScannerConfigure--><bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property><property name="basePackage" value="org.javatop.dao"></property></bean>@MapperScan(basePackages={"org.javatop.dao"}) ---> 配置bean完成
2.2 编码
1. 实体
2. 表
3. DAO接口
4. Mapper文件 
2.3 细节分析:

MapperLocations编码时通配的写法

//设置Mapper文件的路径 这种方式只能设置一个文件
sqlSessionFactoryBean.setMapperLocations(Resource..);
Resource resouce = new ClassPathResouce("UserDAOMapper.xml")sqlSessionFactoryBean.setMapperLocations(new ClassPathResource("UserDAOMapper.xml"));

xml设置一组Mapper文件:

  <property name="mapperLocations"><list><value>classpath:org.javatop.mapper/*Mapper.xml</value></list></property>

java代码设置一组Mapper文件:

ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("org.javatop.mapper/*Mapper.xml");
sqlSessionFactoryBean.setMapperLocations(resources)
2.4 配置Bean数据耦合的问题

提取properties文件:

mybatis.driverClassName = com.mysql.cj.jdbc.Driver
mybatis.url = jdbc:mysql://localhost:3306/Leo?useSSL=false
mybatis.username = root
mybatis.password = root
mybatis.typeAliasesPackages = org.javatop.mybatis
mybatis.mapperLocations = org.javatop.mapper/*Mapper.xml

java代码中获取:

  @Component@PropertySource("classpath:mybatis.properties")public class MybatisProperties {@Value("${mybatis.driverClassName}")private String driverClassName;@Value("${mybatis.url}")private String url;@Value("${mybatis.username}")private String username;@Value("${mybatis.password}")private String password;@Value("${mybatis.typeAliasesPackages}")private String typeAliasesPackages;@Value("${mybatis.mapperLocations}")private String mapperLocations;}public class MyBatisAutoConfiguration {@Autowiredprivate MybatisProperties mybatisProperties;@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(mybatisProperties.getDriverClassName());dataSource.setUrl(mybatisProperties.getUrl());dataSource.setUsername(mybatisProperties.getUsername());dataSource.setPassword(mybatisProperties.getPassword());return dataSource;}@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackages());//sqlSessionFactoryBean.setMapperLocations(new ClassPathResource("UserDAOMapper.xml"));try {ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources(mybatisProperties.getMapperLocations());sqlSessionFactoryBean.setMapperLocations(resources);} catch (IOException e) {e.printStackTrace();}return sqlSessionFactoryBean;}}

3. 纯注解版事务编程:

1. 原始对象 XXXService<bean id="userService" class="org.javatop.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/></bean>@Servicepublic class UserServiceImpl implements UserService{@Autowiredprivate UserDAO userDAO;}2. 额外功能<!--DataSourceTransactionManager--><bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>@Beanpublic DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){DataSourceTransactionManager dstm = new DataSourceTransactionManager();dstm.setDataSource(dataSource);return dstm }3. 事务属性@Transactional@Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;4. 基于Schema的事务配置 <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>@EnableTransactionManager ---> 配置Bean

9.总结

以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。

如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/114237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 创建或读取 Excel 文件

Excel是一种常用的电子表格软件&#xff0c;广泛应用于金融、商业和教育等领域。它提供了强大的数据处理和分析功能&#xff0c;可进行各种计算和公式运算&#xff0c;并能创建各种类型的图表和可视化数据。Excel的灵活性使其成为处理和管理数据的重要工具。本文将介绍如何使用…

【微信小程序】6天精准入门(第5天:利用案例与后台的数据交互)附源码

一、什么是后台交互&#xff1f; 在小程序中&#xff0c;与后台交互指的是小程序前端与后台服务器之间的数据通信和请求处理过程。通过与后台交互&#xff0c;小程序能够获取服务器端的数据、上传用户数据、发送请求等。 小程序与后台交互可以实现数据的传输、用户认证、实时消…

什么是Sectigo证书?

Sectigo证书&#xff0c;早前被称为Comodo证书&#xff0c;是一种SSL&#xff08;安全套接层&#xff09;证书&#xff0c;用于保护互联网上的数据传输的安全性和隐私性。这些证书由全球领先的SSL证书颁发机构Sectigo颁发&#xff0c;被广泛用于网站、应用程序和服务器上。本文…

hexo发生错误 Error: Spawn failed

错误描述 仓库中有东西&#xff0c;运行如下命令后报错 hexo d报错提示: 原因分析: 看别人的博客是用git进行push或hexo d的时候改变了一些.deploy_git文件下的内容&#xff0c;这个.deploy_git的内容对于hexo来说可能是系统文件&#xff0c;这里挖坑 解决办法 一个个的…

分布式Trace:横跨几十个分布式组件的慢请求要如何排查?

目录 前言 一、问题的出现&#xff1f; 二、一体化架构中的慢请求排查如何做 三、分布式 Trace原理 四、如何来做分布式 Trace 前言 在分布式服务架构下&#xff0c;一个 Web 请求从网关流入&#xff0c;有可能会调用多个服务对请求进行处理&#xff0c;拿到最终结果。这个…

自然语言处理---注意力机制

注意力概念 观察事物时&#xff0c;之所以能够快速判断一种事物(当然允许判断是错误的)&#xff0c;是因为大脑能够很快把注意力放在事物最具有辨识度的部分从而作出判断&#xff0c;而并非是从头到尾的观察一遍事物后&#xff0c;才能有判断结果。正是基于这样的理论&#xf…

函数和执行上下文

一.变量提升与函数提升 变量提升&#xff1a;通过var关键字定义&#xff08;声明&#xff09;的变量&#xff0c;在定义语句之前就可以访问到&#xff0c;只不过其值是undefined 函数提升&#xff1a;通过function声明的函数&#xff0c;在之前就可以调用&#xff0c;值是函数…

聊一聊如何在Vue中使用事件总线( Event Bus)进行组件间通信

事件总线模式允许不同的组件之间进行通信。它要求一个中央枢纽&#xff0c;组件可以通过它发送和接收事件&#xff0c;从而使组件之间的数据交换和交互更加顺畅。本文探讨了它的使用方法&#xff0c;以便开发人员能够充分利用它在Vue开发中的潜力。 跨通信是应用程序中组件之间…

STM32F4X定时器之基本定时器

一、定时器的概述 进行有规律的计数&#xff0c;每记一次数的时间都是固定的 定时器的本质&#xff1a;计数的总时间 记一次数的时间&#xff08;时钟的频率&#xff09; * 记多少次&#xff08;重装载值&#xff09;。 基本定时器属于片上外设&#xff0c;系统滴答定时器是…

GitHub下载太慢的解决方案

修改hosts文件&#xff1a; windows的hosts文件在 C:\Windows\System32\drivers\etc\hosts cmd管理员运行命令notepad C:\Windows\System32\drivers\etc\hosts 然后cmd命令重启网络ipconfig /flushdns windows修改hosts Ubuntu22.04修改hosts sudo vim /etc/hosts # This fil…

openEuler 服务器安装 JumpServer (all-in-one 模式)

openEuler 服务器安装 JumpServer JumpServer 简介什么是 JumpServer &#xff1f;JumpServer 的各种类型资产JumpServer 产品特色或优势JumpServer 符合 4A 规范 JumpServer 系统架构应用架构组件说明 JumpServer 安装部署环境要求网络端口网络端口列表防火墙常用命令 在线脚本…

vlookup函数踩坑(wps)

使用wps的朋友看过来 vlookup函数踩坑&#xff0c;vlookup&#xff08;查找值&#xff0c;查找范围&#xff0c;返回值的索引&#xff0c;精确查找or模糊查找&#xff09; 我们要查找的数据的那一列&#xff0c;必须是查找范围的第一列&#xff01; 案例&#xff0c;看下面的…

02、Python 字符串

目录 字符串的基础用法字符串包含引号字符串拼接获取用户输入长字符串原始字符串字节串字符串与字节串转换 字符串的基础用法 列字符串的内容几乎可以包含任何字符&#xff0c;英文字符也行&#xff0c;中文字符也行。 既可用单引号&#xff0c;也可用双引号 字符串包含引号…

shell的for循环与结构化

shell笔记 列表for循环不带列表for循环for循环举例1.例1 所有文件名大写替换为小写2. 例2 读取/etc/passwd文件&#xff0c;依次输出ip段3. 例3 读取/etc/hosts内容for循环&#xff0c;执行ping4. 例4 循环ip列表&#xff0c;输出对应编号5. 例5 批量添加用户 break1. 例1 brea…

C++ vector 的模拟实现

目录 1. vector 类的成员变量 2. 无参构造 3. 析构函数 4. size_t capacity() 5. size_t size() 6. void reserve(size_t n) 7. 迭代器 8. void push_back(const T& x) 9. T& operator[](size_t pos) 10. iterator insert(iterator pos, const T& val…

MySQL 三大日志(bin log、redo log、undo log)

redo log redo log (重做日志) 是 InnoDB 存储引擎独有的&#xff0c;它让 MySQL有了崩溃恢复的能力&#xff0c;是事务中实现 持久化的重要操作 比如 MySQL 实例宕机了&#xff0c;重启时&#xff0c;InnoDB 存储引擎会使用 redo log 恢复数据&#xff0c;保证数据的持久性与…

设计模式——七大原则详解

目录 设计模式单一职责原则应用实例注意事项和细节 接口隔离原则应用实例 依赖倒转&#xff08;倒置&#xff09;原则基本介绍实例代码依赖关系传递的三种方式注意事项和细节 里氏替换原则基本介绍实例代码 开闭原则基本介绍实例代码 迪米特法则基本介绍实例代码注意事项和细节…

golang笔记17--编译调试go源码

golang笔记17--编译调试go源码 前置条件编译源码在 fmt 包中加自定义函数说明 当前go语言越来越流行了&#xff0c;各大厂商都有加大go工程师的需求&#xff0c;作为go语言的学习者&#xff0c;我们除了要了解如何使用go语言外&#xff0c;也有必要了解一下如何编译、调试go源码…

解决XXLJOB重复执行问题--Redis加锁+注解+AOP

基于Redis加锁注解AOP解决JOB重复执行问题 现象解决方案自定义注解定义AOP策略redis 加锁实践 现象 线上xxljob有时候会遇到同一个任务在调度的时候重复执行&#xff0c;如下图&#xff1a; 线上JOB服务运行了2个实例&#xff0c;有时候会重复调度到同一个实例&#xff0c;有…

交换机端口灯常亮 端口up状态 服务器设置ip交换机获取不到服务器网卡mac地址 不能通信

环境: 深信服防火墙 8.0.75 AF-2000-FH2130B-SC S6520X-24ST-SI交换机 version 7.1.070, Release 6530P02 问题描述: 交换机一个vlan下有3台服务器,连接端口2、3、4,2和3连接的服务器正常,交换机3端口灯常亮 端口up状态 服务器自动获取不了地址,改为手动设置ip后,交…