软件编程
位置:首页>> 软件编程>> java编程>> Springboot自动装配实现过程代码实例

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

作者:Zs夏至  发布时间:2023-11-14 19:50:19 

标签:Spring,boot,自动,装配

创建一个简单的项目:


<?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();
 }
}

启动类要引入配置文件:

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

import注解引入配置文件。

编写测试类测试:


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

@Autowired
 public MyConsumer myConsumer;

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

来源:https://www.cnblogs.com/Zs-book1/p/12540571.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com