代码拉取完成,页面将自动刷新
import org.springframework.stereotype.Component;
@Component
public class MyBean {
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
// @Configuration也可以
@Component
public class MyFactoryBean implements FactoryBean<Abc> {
/**
* 返回要往容器中注册的bean <br/>
*
* @return 要往容器中注册的bean <br/> 注:此bean的bean-name、bean-id为myFactoryBean
*/
@Override
public Abc getObject() throws Exception {
return new Abc();
}
/**
* bean的类型
*/
@Override
public Class<?> getObjectType() {
return Abc.class;
}
/**
* 是否是单例模式
*/
@Override
public boolean isSingleton() {
return true;
}
}
提示:通过FactoryBean注册到spring容器中的bean的bena-id为
FactoryBean的类名首字母小写
;而容器中该FactoryBean本身的bean-id为&
+FactoryBean的类名首字母小写
;我们基于上面的代码,进行简单说明:import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class SpringBootDemoApplication implements ApplicationRunner { @Autowired ApplicationContext applicationContext; public static void main(String[] args) { SpringApplication.run(SpringBootDemoApplication.class, args); } @Override public void run(ApplicationArguments args) throws Exception { // 输出:com.ideaaeid.demo.Abc@d400943 System.out.println(applicationContext.getBean("myFactoryBean")); // 输出:com.ideaaeid.demo.MyFactoryBean@22101c80 System.out.println(applicationContext.getBean("&myFactoryBean")); } }
注:FactoryBean中的创建Bean对象是懒加载的
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(MyBean.class)
public class MyConfiguration {
}
import com.szlaozicl.mybatisplusdemo.util.DynamicLoadJarClass;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
/**
* 搭配@Component、@Configuration之类的都行
*
*/
@Component
@Import(MyConfiguration.MyImportSelector.class)
public class MyConfiguration {
public static class MyImportSelector implements ImportSelector {
/**
* 注册bean
*
* @param annotationMetadata
* 被@Import(MyImportSelector.class)标注了的类上的所有(RetentionPolicy.RUNTIME级或RetentionPolicy.CLASS级的)注解的信息
*
* @return 需要注册进spring中的类的全类名(注: 注册到spring时, bean-id、bean-name也为全类名)
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 比如这里:要往spring中注册的就是DynamicLoadJarClass类
return new String[]{DynamicLoadJarClass.class.getName()};
}
}
}
补充:
示例一:
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
/**
* 搭配@Component、@Configuration之类的都行
*/
@Component
@Import(MyConfiguration.MyImportBeanDefinitionRegistrar.class)
public class MyConfiguration {
public static class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* 注册bean
*
* @param annotationMetadata
* 被@Import(MyImportBeanDefinitionRegistrar.class)标注了的类上的所有(RetentionPolicy.RUNTIME级
* 或RetentionPolicy.CLASS级的)注解的信息
* @param registry
* 注册器
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("my-bean-name", new RootBeanDefinition(MyBean.class));
// 如果需要构建复杂的BeanDefinition,你可以使用BeanDefinitionBuilder来完成, 如:
// BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class);
// // 字段需要有setter方法才能写入成功,否者会报错
// builder.addPropertyValue("name", "JustryDeng");
// builder.addPropertyValue("age", 18);
// registry.registerBeanDefinition("my-bean-name", builder.getBeanDefinition());
}
}
}
示例二:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Import;
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;
import org.springframework.stereotype.Component;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 搭配@Component、@Configuration之类的都行
*/
@Component
@Import(MyConfiguration.MyImportBeanDefinitionRegistrar.class)
public class MyConfiguration {
public static class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private ResourceLoader resourceLoader;
/**
* 注册bean
*
* @param annotationMetadata
* 被@Import(MyImportBeanDefinitionRegistrar.class)标注了的类上的所有(RetentionPolicy.RUNTIME级
* 或RetentionPolicy.CLASS级的)注解的信息
* @param registry
* 注册器
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
/*
* 以下代码实现功能:将com包下被@MyComponent注解标注的类注册进spring中
* <br/>
* 注:此方式注入,则该bean的bean-id、bean-name默认为首字母小写的类名, 如: 这里的 myConfiguration.MyBean
*/
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
scanner.setResourceLoader(resourceLoader);
scanner.addIncludeFilter(new AnnotationTypeFilter(MyComponent.class));
scanner.scan("com");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
/**
* 自定义注解
*/
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {
}
/**
* 目的:将此类注入spring容器中
*/
@MyConfiguration.MyComponent
public static class MyBean {
@Autowired
DynamicLoadJarClass dynamicLoadJarClass;
}
}
补充:
上图中说的通过ImportSelector返回,即形如:
@Configuration @Import(MyConfiguration.MyImportSelector.class) public class MyConfiguration { public static class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{MyImportBeanDefinitionRegistrar.class.getName()}; } } public static class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { // ... } } }
示例三:获取注解信息
第一步:定义自己的ImportBeanDefinitionRegistrar,这里为ParameterRecorderRegistrar
import com.ideaaedi.commonspring.annotation.EnableParameterRecorder;
import com.ideaaedi.commonspring.enums.ParameterHandleModeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNull;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* ParameterRecorder 注册器
*
* @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
* @since 1.0.0
*/
@Slf4j
public class ParameterRecorderRegistrar implements ImportBeanDefinitionRegistrar {
/**
* 注册bean
*
* @param annotationMetadata
* 被@Import(MyImportBeanDefinitionRegistrar.class)标注了的类上的所有(RetentionPolicy.RUNTIME级
* 或RetentionPolicy.CLASS级的)注解的信息
* @param registry
* 注册器
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata,
@NonNull BeanDefinitionRegistry registry) {
Set<String> includePrefixes = null;
Set<String> excludePrefixes = null;
ParameterHandleModeEnum parameterHandleMode = null;
Boolean pretty = null;
//noinspection rawtypes
Class[] ignoreParamTypes = null;
Map<String, Object> attributeMap = annotationMetadata.getAnnotationAttributes(EnableParameterRecorder.class.getName());
if (attributeMap != null) {
includePrefixes =
Arrays.stream(((String[]) attributeMap.get("includePrefixes"))).collect(Collectors.toSet());
excludePrefixes =
Arrays.stream(((String[]) attributeMap.get("excludePrefixes"))).collect(Collectors.toSet());
parameterHandleMode = (ParameterHandleModeEnum) attributeMap.get("parameterHandleMode");
pretty = (boolean) attributeMap.get("pretty");
//noinspection rawtypes
ignoreParamTypes = (Class[]) attributeMap.get("ignoreParamTypes");
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ParameterRecorder.class);
builder.addConstructorArgValue(includePrefixes);
builder.addConstructorArgValue(excludePrefixes);
if (parameterHandleMode != null) {
builder.addConstructorArgValue(parameterHandleMode);
}
if (pretty != null) {
builder.addConstructorArgValue(pretty);
}
if (ignoreParamTypes != null) {
builder.addConstructorArgValue(ignoreParamTypes);
}
log.info("register spring-bean parameterRecorder with ConstructorArg includePrefixes -> {}, "
+ "excludePrefixes -> {}, parameterHandleMode -> {}, pretty -> {}, ignoreParamTypes -> {}",
includePrefixes, excludePrefixes, parameterHandleMode, pretty, ignoreParamTypes);
registry.registerBeanDefinition("parameterRecorder", builder.getBeanDefinition());
}
}
第二步:定义一个注解,快速import ParameterRecorderRegistrar
import com.ideaaedi.commonspring.aop.ParameterRecorderRegistrar;
import com.ideaaedi.commonspring.enums.ParameterHandleModeEnum;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 启用参数记录器
*
* @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
* @since 1.0.0
*/
@Inherited
@Documented
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@Import(ParameterRecorderRegistrar.class)
public @interface EnableParameterRecorder {
/**
* 需要包含的methodReference前缀
* <br/>
* 为空则表示全部包含
* <br/>
* methodReference形如: com.ideaaedi.commonspring.aop.ParameterRecorder#init
*/
String[] includePrefixes() default {};
/**
* 需要排除的methodReference前缀
* <br/>
* 为空则表示都不需要排除
* <br/>
* methodReference形如: com.ideaaedi.commonspring.aop.ParameterRecorder#init
*/
String[] excludePrefixes() default {};
/**
* 将参数转换为字符串的方式
*/
ParameterHandleModeEnum parameterHandleMode() default ParameterHandleModeEnum.USE_JSON;
/**
* 记录日志时,是否美化
*/
boolean pretty() default true;
/**
* 当参数类型是这些时,不打印该参数
*/
Class[] ignoreParamTypes() default {};
}
第二步:使用注解
@SpringBootApplication
@EnableParameterRecorder(includePrefixes = "com.ideaaedi.springcloud.jd", ignoreParamTypes = {MultipartFile.class, HttpServletRequest.class, HttpServletResponse.class})
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
那么注解上的值,在ParameterRecorderRegistrar中能对应获取到
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;
// @Configuration也可以
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Abc.class);
// 字段需要有setter方法才能写入成功,否者会报错
builder.addPropertyValue("name", "JustryDeng");
builder.addPropertyValue("age", 18);
beanDefinitionRegistry.registerBeanDefinition("abc", builder.getBeanDefinition());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
......
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。