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

网友投稿 245 2022-12-05


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

创建一个简单的项目:

xmlns:xsi="http://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">

4.0.0

spring-boot-starter-parent

org.springframework.boot

2.1.12.RELEASE

com.xiazhi

demo

1.0-SNAPSHOT

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

xmlns:xsi="http://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">

4.0.0

spring-boot-starter-parent

org.springframework.boot

2.1.12.RELEASE

com.xiazhi

demo

1.0-SNAPSHOT

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

首先创建自定义注解:

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.PostConstructhttp://;

/**

* @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();

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot集成WebSocket长连接实际应用详解
下一篇:Springboot jar主清单属性丢失解决方案
相关文章

 发表评论

暂时没有评论,来抢沙发吧~