Spring系列:基于注解的方式构建IOC

2024-03-04 0 1,959

目录

Java 5 开始,Java 增加了注解Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

Spring 通过注解实现自动装配的步骤如下:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

一、搭建子模块spring6-ioc-annotation

①添加依赖

    <dependencies>
        <dependency>
            <groupId>gt;org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.13</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.20.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>2.20.0</version>
        </dependency>
    </dependencies>

二、添加配置类

AppConfig.java

package com.mcode.config;

import com.mcode.controller.UserController;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

/**
 * ClassName: AppConfig
 * Package: config
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:46 PM
 * @Version: v1.0
 */
@ComponentScan("com.mcode")
public class AppConfig {
}

ComponentScan顾名思义包扫描,底层其实就可以通过递归算法+反射将其装载成bean来实现的,实在开发过程中,Spring已经帮我们实现好了,我们其实就可以直接使用XML或者注解的形式来进行业务处理。

@ComponentScan注解有两个作用

作用一:扫描含有@Component,@Controller,@Service和@Repository的类,并将其注入到spring容器中。

作用二:扫描含有@Configuration的类,并使其生效。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)//可重复注解
public @interface ComponentScan {

   @AliasFor("basePackages")
   String[] value() default {};//基础包名,等同于basePackages

   @AliasFor("value")
   String[] basePackages() default {};//基础包名,value

   Class<?>[] basePackageClasses() default {};//扫描的类,会扫描该类所在包及其子包的组件。

   Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;//注册为BeanName生成策略 默认BeanNameGenerator,用于给扫描到的Bean生成BeanName

   Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;//用于解析bean的scope的属性的解析器,默认是AnnotationScopeMetadataResolver

   ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;//scoped-proxy 用来配置代理方式 // no(默认值):如果有接口就使用JDK代理,如果没有接口就使用CGLib代理 interfaces: 接口代理(JDK代理) targetClass:类代理(CGLib代理)

   String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;//配置要扫描的资源的正则表达式的,默认是"**/*.class",即配置类包下的所有class文件。
  
   boolean useDefaultFilters() default true;//useDefaultFilters默认是true,扫描带有@Component ro @Repository ro @Service ro @Controller 的组件

   Filter[] includeFilters() default {};//包含过滤器

   Filter[] excludeFilters() default {};//排除过滤器

   boolean lazyInit() default false;//是否是懒加载

   @Retention(RetentionPolicy.RUNTIME)
   @Target({})
   @interface Filter {//过滤器注解

      FilterType type() default FilterType.ANNOTATION;//过滤判断类型

      @AliasFor("classes")
      Class<?>[] value() default {};//要过滤的类,等同于classes

      @AliasFor("value")
      Class<?>[] classes() default {};//要过滤的类,等同于value

      String[] pattern() default {};// 正则化匹配过滤

   }
}

演示

@ComponentScan(value = "com.mcode", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
                classes = {UserController.class})},
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Component.class})}
)

三、使用注解定义 Bean

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。

注解 说明
@Component 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

单独写一个配置类来配置Bean

  • @Bean 注解扮演与 元素相同的角色。用到方法上,表示当前方法的返回值是一个bean
  • @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 Bean 间依赖关系。相当于spring的配置文件XML

四、@Autowired注入

单独使用@Autowired注解,默认根据类型装配。【默认是byType】

查看源码:

源码中有两处需要注意:

  • 第一处:该注解可以标注在哪里?

    • 构造方法上
    • 方法上
    • 形参上
    • 属性上
    • 注解上
  • 第二处:该注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在的话就注入,不存在的话,也不报错。

  • @Autowired注解可以出现在:属性上、构造方法上、构造方法的参数上、setter方法上。

  • 当带参数的构造方法只有一个,@Autowired注解可以省略。()

  • @Autowired注解默认根据类型注入。如果要根据名称注入的话,需要配合@Qualifier注解一起使用。

五、@Resource注入

@Resource注解也可以完成属性注入。那它和@Autowired注解有什么区别?

  • @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
  • @Autowired注解是Spring框架自己的。
  • @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。
  • @Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。
  • @Resource注解用在属性上、setter方法上。
  • @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

@Resource注解属于JDK扩展包,所以不在JDK当中,需要额外引入以下依赖:【如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖。

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

六、全部代码

UserDaoImpl

package com.mcode.dao.impl;

import com.mcode.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * ClassName: UserDaoImpl
 * Package: com.mcode.dao.impl
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:54 PM
 * @Version: v1.0
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Override
    public void getUser() {
        System.out.println("user dao...");
    }
}

UserDao

package com.mcode.dao;

/**
 * ClassName: UserDao
 * Package: com.mcode.dao
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:54 PM
 * @Version: v1.0
 */
public interface UserDao {
    void getUser();
}

UserServiceImpl

package com.mcode.service.impl;

import com.mcode.dao.UserDao;
import com.mcode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * ClassName: UserServiceImpl
 * Package: com.mcode.service.impl
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:48 PM
 * @Version: v1.0
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public void getUser() {
         userDao.getUser();
    }
}

UserService

package com.mcode.service;

/**
 * ClassName: UserService
 * Package: com.mcode.service
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:47 PM
 * @Version: v1.0
 */
public interface UserService {
    void getUser();
}

UserController

package com.mcode.controller;

import com.mcode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * ClassName: UserController
 * Package: com.mcode.controller
 * Description:
 *
 * @Author: robin
 * @Create: 2023/11/8 - 9:49 PM
 * @Version: v1.0
 */
@Controller
public class UserController {

    @Autowired
    private UserService userService;

    public void getUser(){
        userService.getUser();
    }
}

AppTest

package com.mcode;

import com.mcode.config.AppConfig;
import com.mcode.controller.UserController;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Hello world!
 *
 */
public class AppTest
{
   @Test
    public void testAnnotation(){
       AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
       UserController userController = (UserController) context.getBean(UserController.class);
       userController.getUser();
   }
}
资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Spring系列:基于注解的方式构建IOC http://www.20zxx.cn/808710/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务