zoukankan      html  css  js  c++  java
  • 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>
    pom

    首先创建自定义注解:

    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("测试案例");
        }
    }
    View Code
    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();
        }
    }
    View Code

    启动类要引入配置文件:

     import注解引入配置文件。

    编写测试类测试:

    @SpringBootTest(classes = ApplicationRun.class)
    @RunWith(SpringRunner.class)
    public class TestDemo {
    
        @Autowired
        public MyConsumer myConsumer;
    
        @Test
        public void fun1() {
            myConsumer.aaa();
        }
    }
  • 相关阅读:
    Hibernate延迟加载、三种状态、脏检查 缓存
    Hibernate入门案例
    Hibernate入门案例及增删改查
    PasswordHelper 对user对象的password进行加密重设
    shrio 加密/编码
    shrio int配置
    shrio 授权
    JUnit中assertEquals和assertSame方法的不同
    shrio 身份认证流程-Realm
    shrio 登录/退出
  • 原文地址:https://www.cnblogs.com/Zs-book1/p/12540571.html
Copyright © 2011-2022 走看看