SpringBoot前置知识02-spring注解发展史

2024-05-23 23:28

本文主要是介绍SpringBoot前置知识02-spring注解发展史,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

springboot前置知识01-spring注解发展史

spring1.x

spring配置只能通过xml配置文件的方式注入bean,需要根据业务分配配置文件,通过import标签关联。

spring1.2版本出现@Transactional注解

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userService" class="com.shaoby.service.UserServiceImpl"></bean>
</beans>
public class UserServiceImpl {
}
public class StartApp {public static void main(String[] args) {ClassPathXmlApplicationContext cp = new ClassPathXmlApplicationContext("applicationContext.xml");Object userService = cp.getBean("userService");System.out.println(userService);}
}

spring2.X

  1. 简化配置,通过compoment-scan和@Component(2.0)、 @Controller(2.5)、@Service(2.5)、 @Repository(2.5)注解实现bean管理
  2. context:annotation-config标签向spring容器中注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor,可以使用@ Resource 、@ PostConstruct、@ PreDestroy等注解
  3. 使用compoment-scan后可以将context:annotation-config移除
  4. 2.X版本没有脱离配置文件
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--    <context:annotation-config/>--><context:component-scan base-package="com.shaoby.*" />
</beans>
@Component
public class OtherServiceImpl {
}@Component
public class UserServiceImpl {@Autowiredprivate OtherServiceImpl otherService;
}
public class AppStart {public static void main(String[] args) {ClassPathXmlApplicationContext cp = new ClassPathXmlApplicationContext("applicationContext.xml");for (String beanDefinitionName : cp.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}}
}

spring3.X

spring3.0

  1. 新增@Configuration标记类为配置类,代替applicationContext.xml文件;@Bean注解注入对象,相当于xml中的bean标签;
  2. 无法脱离配置文件,需要借助context即xml中的compoment-scan标签,否则无法识别@Component、@Controller、@Service、@Repository注解;
  3. 提供@ImportResource注解,关联applicationContext配置文件;
  4. 所以就升级成@Configuration注解+applicationContext.xml配合Bean注解使用或者@Configuration注解+applicationContext.xml配合@Component等四个注解使用
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.shaoby.*" />
</beans>
@Configuration
@ImportResource("classpath:applicationContext.xml")
public class AppConfig {@Beanpublic OtherServiceImpl otherService(){return new OtherServiceImpl();}
}
@Service
public class UserServiceImpl {
}public class OtherServiceImpl {
}
public class AppStart {public static void main(String[] args) {ApplicationContext ap = new AnnotationConfigApplicationContext(AppConfig.class);for (String beanDefinitionName : ap.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}}
}

spring3.1

1. 新增@ComportScan注解,默认扫描当前包及其子包下是@Component等四个注解修饰的所有类,脱离配置文件;
@Configuration
@ComponentScan("com.shaoby.*")
public class AppConfig {
}
@Component
public class OtherServiceImpl {
}
@Service
public class UserServiceImpl {
}
2. 新增@Import注解
  1. 代替import标签,在配置类中导入其他配置类
@Configuration
public class OtherConfig {@Beanpublic OtherServiceImpl otherService(){return new OtherServiceImpl();}
}@Configuration
@ComponentScan("com.shaoby.*")
@Import({OtherConfig.class})
public class AppConfig {
}
  1. 可以在配置类中直接导入bean
@Configuration
@Import(StudentServiceImpl.class)
public class OtherConfig {@Beanpublic OtherServiceImpl otherService(){return new OtherServiceImpl();}
}public class StudentServiceImpl {
}
  1. 高级用法-动态注入

    @Import注解如果引入了实现ImportSelector注解的类,不会将该类型注入到容器中,而是将selectImports方法返回类型的全类路径字符串的数据注入到容器中

public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{Logger.class.getName(),Redis.class.getName()};}
}@Configuration
@Import(MyImportSelector.class)
public class JavaConfig {public static void main(String[] args) {ApplicationContext ap = new AnnotationConfigApplicationContext(JavaConfig.class);for (String beanDefinitionName : ap.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}}
}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
javaConfig
com.shaoby.importtest.Logger
com.shaoby.importtest.Redis

@Import注解如果引入了实现ImportBeanDefinitionRegistrar的类也可以

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {registry.registerBeanDefinition("logger", new RootBeanDefinition(Logger.class));registry.registerBeanDefinition("redis", new RootBeanDefinition(Redis.class));}
}@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class JavaConfig {public static void main(String[] args) {ApplicationContext ap = new AnnotationConfigApplicationContext(JavaConfig.class);for (String beanDefinitionName : ap.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}}
}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
javaConfig
logger
redis
3. 新增Enabled模块,即EnabledXXX注解,它是结合@Import注解使用的
@Configuration
public class RedisAutoConfiguration {@Beanpublic RedisTemplate redisTemplate(){return new RedisTemplate();}
}public class RedisTemplate {
}

定义开关注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(RedisAutoConfiguration.class)
public @interface EnabledAutoRedisConfiguration {
}
@Configuration
@EnabledAutoRedisConfiguration
public class AppConfig {
}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig
com.shaoby.ebabledtest.RedisAutoConfiguration
redisTemplate

注掉@EnabledAutoRedisConfiguration

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig

spring4.X

新增注解:@Conditional(条件注解),@EventListListener(事件监听),@AliasFor(别名),@CrossOrigin(解决跨域问题)

@Conditional注解

这个注解控制在什么条件下注入bean,这个注解传入一个实现Condition接口的类

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {/*** All {@link Condition} classes that must {@linkplain Condition#matches match}* in order for the component to be registered.*/Class<? extends Condition>[] value();}

在Condition的实现类中可以根据需求判断是否需要注入容器中

@FunctionalInterface
public interface Condition {/*** Determine if the condition matches.* @param context the condition context* @param metadata the metadata of the {@link org.springframework.core.type.AnnotationMetadata class}* or {@link org.springframework.core.type.MethodMetadata method} being checked* @return {@code true} if the condition matches and the component can be registered,* or {@code false} to veto the annotated component's registration*/boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}

实战

public class JavaConfig {/** 根据MyConditionalOnClass中matches方法返回值判断是否将UsersService注入到容器中*/@Conditional(MyConditionalOnClass.class)@Beanpublic UserService userService(){return new UserService();}public static void main(String[] args) {ApplicationContext ap = new AnnotationConfigApplicationContext(JavaConfig.class);for (String beanDefinitionName : ap.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}}
}public class MyConditionalOnClass implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {/** 根据需求判断是否需要将bean注入到容器中*/boolean userServiceFlag = context.getRegistry().containsBeanDefinition("userService");return userServiceFlag;}
}public class UserService {
}

spring5.X

新增@Indexed(类索引),需要引入依赖。它被标识在@Component注解上,会在编译时会在MATE-INF文件夹下生成spring.components文件夹存储要DI的所有类的全类路径。这样会提高代码启动速度。

<dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId>
</dependency>

总结

在spring的发展中注解的开发已经为SpringBoot的诞生做好了铺垫,其中@EnabledAutoXXXConfiguration、@ConditionalOnXXX、@Import等注解是SpringBoot自动装配原理的核心注解。

这篇关于SpringBoot前置知识02-spring注解发展史的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/996719

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B