Springboot自动装配实现过程代码实例

 更新时间:2020年06月11日 09:41:34   作者:Zs夏至  
这篇文章主要介绍了Springboot自动装配实现过程代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

创建一个简单的项目:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.1.12.RELEASE</version>
  </parent>

  <groupId>com.xiazhi</groupId>
  <artifactId>demo</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
  </dependencies>
</project>

首先创建自定义注解:

package com.xiazhi.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * MyComponent 作用于类上,表示这是一个组件,于component,service注解作用相同
 * @author zhaoshuai
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {

}
package com.xiazhi.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 作用于字段上,自动装配的注解,与autowired注解作用相同
 * @author zhaoshuai
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Reference {
}

然后写配置类:

package com.xiazhi.demo.config;

import com.xiazhi.demo.annotation.MyComponent;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;


/**
 * @author ZhaoShuai
 * @company lihfinance.com
 * @date Create in 2020/3/21
 **/
public class ComponentAutoConfiguration implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

  private ResourceLoader resourceLoader;

  @Override
  public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
    String className = annotationMetadata.getClassName();
    String basePackages = className.substring(0, className.lastIndexOf("."));

    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry, false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(MyComponent.class));
    scanner.scan(basePackages);
    scanner.setResourceLoader(resourceLoader);
  }

  @Override
  public void setResourceLoader(ResourceLoader resourceLoader) {
    this.resourceLoader = resourceLoader;
  }

}

上面是配置扫描指定包下被MyComponent注解标注的类并注册为spring的bean,bean注册成功后,下面就是属性的注入了

package com.xiazhi.demo.config;

import com.xiazhi.demo.annotation.MyComponent;
import com.xiazhi.demo.annotation.Reference;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

/**
 * @author ZhaoShuai
 * @company lihfinance.com
 * @date Create in 2020/3/21
 **/
@SpringBootConfiguration
public class Configuration implements ApplicationContextAware {
  private ApplicationContext applicationContext;

  @Bean
  public BeanPostProcessor beanPostProcessor() {
    return new BeanPostProcessor() {

      /**
       * @company lihfinance.com
       * @author create by ZhaoShuai in 2020/3/21
       * 在bean注册前会被调用
       * @param [bean, beanName]
       * @return java.lang.Object
       **/
      @Override
      public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
      }

      /**
       * @company lihfinance.com
       * @author create by ZhaoShuai in 2020/3/21
       * 在bean注册后会被加载,本次在bean注册成功后注入属性值
       * @param [bean, beanName]
       * @return java.lang.Object
       **/
      @Override
      public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clazz = bean.getClass();
        if (!clazz.isAnnotationPresent(MyComponent.class)) {
          return bean;
        }

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
          if (!field.isAnnotationPresent(Reference.class)) {
            continue;
          }
          Class<?> type = field.getType();
          Object obj = applicationContext.getBean(type);
          ReflectionUtils.makeAccessible(field);
          ReflectionUtils.setField(field, bean, obj);
        }
        return bean;
      }
    };
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }
}

下面开始使用注解来看看效果:

package com.xiazhi.demo.service;

import com.xiazhi.demo.annotation.MyComponent;

import javax.annotation.PostConstruct;

/**
 * @author ZhaoShuai
 * @company lihfinance.com
 * @date Create in 2020/3/21
 **/
@MyComponent
public class MyService {

  @PostConstruct
  public void init() {
    System.out.println("hello world");
  }

  public void test() {
    System.out.println("测试案例");
  }
}
package com.xiazhi.demo.service;

import com.xiazhi.demo.annotation.MyComponent;
import com.xiazhi.demo.annotation.Reference;

/**
 * @author ZhaoShuai
 * @company lihfinance.com
 * @date Create in 2020/3/21
 **/
@MyComponent
public class MyConsumer {

  @Reference
  private MyService myService;

  public void aaa() {
    myService.test();
  }
}

启动类要引入配置文件:

import注解引入配置文件。

编写测试类测试:

@SpringBootTest(classes = ApplicationRun.class)
@RunWith(SpringRunner.class)
public class TestDemo {

  @Autowired
  public MyConsumer myConsumer;

  @Test
  public void fun1() {
    myConsumer.aaa();
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • MyBatis执行Sql的流程实例解析

    MyBatis执行Sql的流程实例解析

    这篇文章主要介绍了MyBatis执行Sql的流程实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • java中Arrays.sort()排序方法举例详解

    java中Arrays.sort()排序方法举例详解

    这篇文章主要给大家介绍了关于java中Arrays.sort()排序方法举例详解的相关资料,Java Arrays.sort()方法对数组进行排序,通常情况下直接传入数组,默认升序排序,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • 解析Mybatis延迟加载问题

    解析Mybatis延迟加载问题

    这篇文章主要介绍了Mybatis的延迟加载问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • Java DFA算法案例详解

    Java DFA算法案例详解

    这篇文章主要介绍了Java DFA算法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Java中动态设置JVM参数的方法总结

    Java中动态设置JVM参数的方法总结

    通过动态设置JVM参数,开发者可以更有效地管理资源使用和优化性能,本文将详细阐述如何在Java中动态设置JVM参数,感兴趣的小伙伴可以了解下
    2024-12-12
  • Springboot实现Java邮件任务过程解析

    Springboot实现Java邮件任务过程解析

    这篇文章主要介绍了Springboot实现Java邮件任务过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java中的异常处理机制介绍(非常全面!)

    Java中的异常处理机制介绍(非常全面!)

    异常可能是在程序执行过程中产生的,也可能是程序中throw主动抛出的,下面这篇文章主要给大家介绍了关于Java中异常处理机制的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Java反射机制详解

    Java反射机制详解

    这篇文章主要介绍了Java反射机制,首先简单介绍了反射机制的预备知识,进一步分析了Java反射机制的原理、实现技巧与应用方法,需要的朋友可以参考下
    2015-12-12
  • java普通类如何转javafx程序

    java普通类如何转javafx程序

    这篇文章主要介绍了java普通类如何转javafx程序方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Spring中IoC优点与缺点解析

    Spring中IoC优点与缺点解析

    这篇文章主要为大家详细解析了Spring中IoC优点与缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11

最新评论