Spring5应用之高级注解开发

作者简介 :☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客
当前专栏Spring5应用专栏_Aomsir的博客-CSDN博客

文章目录

参考文献

前言

在上一篇文章中,我们详细介绍了Spring2.x提供的一系列基础注解,并探讨了如何使用这些注解来简化开发。这些注解在Spring框架中的作用不可忽视,它们为开发者提供了更便捷的方式来管理组件、依赖注入以及其他关键方面的配置。本文将继续探讨Spring注解开发,更深入地了解这些强大的工具如何加速开发过程并提高代码质量。

@Configuration

在Spring3.x中引入了一项重要的新注解,即 @Configuration,它通常被称为配置类。这个注解的作用非常强大,它允许我们将Java类标记为配置Bean,以代替繁琐的XML配置文件。实际上,@Configuration是@Component注解的一种特殊形式。

开发步骤:

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

通过使用 @Configuration 注解,我们可以更加方便地管理应用程序的配置,减少对XML配置文件的依赖,同时提高了代码的可维护性和可读性

java 复制代码
@Configuration
public class AppConfig {
}
java 复制代码
public class TestAnnotation2 {

    /**
     * 测试 @Configuration 注解
     */
    @Test
    public void test1() {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    }
}

@Bean

@Bean注解通常用于配置类中,用于声明和创建Bean。它与@Component注解相似,都能够将类标记为由Spring管理的组件。然而,@Bean注解在某些方面与@Component有一些关键的不同之处。

  • 区分简单对象和复杂对象 :在Spring开发中,我们通常将对象分为两类:简单对象和复杂对象。
    • 简单对象:这些对象可以直接使用new操作符进行创建,例如UserUserServiceUserDAO等。
    • 复杂对象:这些对象不适合直接使用new操作符创建,通常是因为它们依赖其他Bean或需要进行复杂的初始化过程,比如SqlSessionSqlSessionFactory等。

@Bean注解主要用于声明和创建复杂对象,因为它允许我们在配置类中定义复杂对象的初始化和依赖关系。

请注意,即使只有类文件可用,并且需要使用注解驱动的开发,也可以使用@Bean注解来定义Bean

开发步骤

  • 创建配置Bean,按照上图要求书写方法
  • 编写测试方法进行验证
java 复制代码
@Configuration
public class AppConfig {

    /**
     * 创建 简单对象
     * @return User
     */
    @Bean
    public User user() {
        return new User();
    }

    @Bean
    public Connection connection() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/blog?useSSL=false&serverTimezone=UTC","root","123456");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}
java 复制代码
public class TestAnnotation2 {
    /**
     * 测试 @Bean 注解 简单对象
     */
    @Test
    public void test2() {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        User user = ctx.getBean("user",User.class);
        System.out.println(user);
    }

    /**
     * 测试 @Bean 注解 复杂对象
     */
    @Test
    public void test3() {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

        Connection connection = ctx.getBean(Connection.class);

        System.out.println("connection = " + connection);
    }
}


自定义类型

对于自定义数据类型,难免会遇到这种情况就是自定义类型的依赖注入,对于我们依赖方和被依赖方都使用@Bean的情况下,我们需要进行依赖注入应该怎么办?Spring会帮我们进行自动注入

  • 依赖方在方法体内用Set直接注入被依赖方即可,Spring会帮我们进行处理
  • 依赖方方法形参写上被依赖方,然后直接用Set方法注入,Spring也会帮我们进行处理,原理一致
    如下两段代码演示即可
java 复制代码
@Configuration
public class AppConfig {

    @Bean
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }

    @Bean
    public UserService userService() {
        UserService userService = new UserServiceImpl();

        // 这里可以直接注入,Spring会帮我们在容器中找
        userService.setUserDao(userDAO);
        return userService;
    }
}
java 复制代码
@Configuration
public class AppConfig {

    @Bean
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }

    @Bean
    public UserService userService(UserDAO userDAO) {
        UserService userService = new UserServiceImpl();

        // 也可以写在方法参数中,Spring也会帮我们进行注入
        userService.setUserDao(userDAO);
        return userService;
    }
}

细节分析

  • 自定义id值可以直接修方法名,也可以使用注解参数@Bean("u")
  • 控制对象的创建次数,可以在方法上标注@Scope并设置对应的值

@ComponentScan

@ComponentScan 注解用于扫描并注册 Spring Bean。它等同于 XML 配置中的 <context:component-scan base-package="" /> 元素。通过在配置类上使用 @ComponentScan 注解,可以告诉 Spring 哪些包需要被扫描,从而将这些包中的 Bean 注入容器中。

此注解具有多个属性,可用于指定包含和排除的规则等。下面是一个示例用法,其中包含和排除是多种多样的,具体的使用方法可以参考官方文档

java 复制代码
@Configuration
@ComponentScan(basePackages = "com.aomsir.basic",
               excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class)},
               includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class)},
               useDefaultFilters = false)
public class AppConfig {
}

纯注解事务开发

在先前的 Spring 事务开发中,我们通常需要在 XML 配置文件中设置数据源dataSourceTransactionManager 等事务相关的配置。

然而,现在我们可以使用纯注解方式来管理事务,只需要创建一个配置类进行配置。接下来,只需在需要事务支持的方法或业务类上添加 @Transactional 注解即可,无需再涉及繁琐的配置。

这种方式极大地简化了事务管理,提高了代码的可维护性

java 复制代码
@Configuration
@EnableTransactionManagement  // 开启事务
public class TransactionAutoConfiguration {
    @Autowired
    private DataSource dataSource;
    
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager() {
        DataTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

AOP纯注解开发

在先前的AOP动态代理开发中,我们已经通过注解方式大大简化了很多内容,如切面类、切入点等。然而,仍然需要在配置文件中声明 <aop:aspectj-autoproxy /> 标签,以允许Spring启用AspectJ,以便使用注解来编写切面。但是,现在我们可以通过纯注解方式来进一步简化这些操作,包括启用AOP。

这种方式极大地减少了XML配置的需求,使AOP编程更加直观和便于维护

java 复制代码
@Configuration
@ComponentScan(basePackages = "com.aomsir.basic.aop")
@EnableAspectJAutoProxy    // 允许Aspect - AOP,SpringBoot已经做了这一步
public class AppConfig {

}
java 复制代码
@Aspect
@Component
public class MyAspect {

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

    @Pointcut("execution(* com.aomsir.basic.aop..*.*(..))")
    public void pointCut(){}

    // 等价于invoke方法
    @Around("pointCut()")
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("----log----");
        Object ret = joinPoint.proceed();
        return ret;
    }
}


@Service
public class UserServiceImpl implements UserService {

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

    @Override
    public void register(User user) {
        log.error("UserServiceImpl.register 业务运算+Dao的调用");
    }

    @Override
    public boolean login(String name, String password) {
        log.error("UserServiceImpl.login 业务运算+Dao的调用");
        return true;
    }
}

总结

这样,Spring中的注解编程完全分析完了。逐步将先前在Spring中使用配置文件的内容转换为注解方式是一种提高开发效率和可维护性的重要方法。Spring的注解编程使代码更加简洁和可读,同时减少了XML配置的需求。这将为以后学习和应用Spring Boot等框架提供坚实的基础

相关推荐
保持学习ing4 分钟前
苍穹外卖day3--公共字段填充+新增菜品
java·阿里云·实战·springboot·前后端·外卖项目·阿里云文件存储
lingRJ7771 小时前
微服务架构下的抉择:Consul vs. Eureka,服务发现该如何选型?
java·eureka·springcloud·consul·backend·microservices·servicediscovery
C182981825751 小时前
OOM电商系统订单缓存泄漏,这是泄漏还是溢出
java·spring·缓存
笑衬人心。1 小时前
Ubuntu 22.04 修改默认 Python 版本为 Python3 笔记
笔记·python·ubuntu
金色光环2 小时前
【Modbus学习笔记】stm32实现Modbus
笔记·stm32·学习
hello早上好2 小时前
JDK 代理原理
java·spring boot·spring
沉着的码农3 小时前
【设计模式】基于责任链模式的参数校验
java·spring boot·分布式
zyxzyx6663 小时前
Flyway 介绍以及与 Spring Boot 集成指南
spring boot·笔记
何苏三月3 小时前
SpringCloud系列 - Sentinel 服务保护(四)
spring·spring cloud·sentinel
纳兰青华3 小时前
bean注入的过程中,Property of ‘java.util.ArrayList‘ type cannot be injected by ‘List‘
java·开发语言·spring·list