• spring boot去除扫描自动注入依赖方法——Spring常用注解使用方法


    问题:
    最近做项目的时候,需要引入其他的jar。然后还需要扫描这些jar里的某些bean。于
    是使用注解:@ComponentScan
    这个注解直接指定包名就可以,它会去扫描这个包下所有的class,然后判断是否解析:

    源码:

    public @interface SpringBootApplication {
        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "exclude"
        )
        Class<?>[] exclude() default {};
    
        @AliasFor(
            annotation = EnableAutoConfiguration.class,
            attribute = "excludeName"
        )
        String[] excludeName() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackages"
        )
        String[] scanBasePackages() default {};
    
        @AliasFor(
            annotation = ComponentScan.class,
            attribute = "basePackageClasses"
        )
        Class<?>[] scanBasePackageClasses() default {};
    }
    
    
    public @interface ComponentScan {
        @AliasFor("basePackages")
        String[] value() default {};
    
        @AliasFor("value")
        String[] basePackages() default {};
    
        Class<?>[] basePackageClasses() default {};
    
        Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    
        Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
    
        ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
    
        String resourcePattern() default "**/*.class";
    
        boolean useDefaultFilters() default true;
    
        ComponentScan.Filter[] includeFilters() default {};
    
        ComponentScan.Filter[] excludeFilters() default {};
    
        boolean lazyInit() default false;
    
        @Retention(RetentionPolicy.RUNTIME)
        @Target({})
        public @interface Filter {
            FilterType type() default FilterType.ANNOTATION;
    
            @AliasFor("classes")
            Class<?>[] value() default {};
    
            @AliasFor("value")
            Class<?>[] classes() default {};
    
            String[] pattern() default {};
        }
    }
    @ComponentScan(basePackages = {"your.pkg", "other.pkg"})
    
    public class Application {
    
    } 

    其他的jar中定义了 redissonConfig 这个bean。然后我自己的项目也定义了redissonConfig 这个bean。导致项目启动报错。所以使用如下方式,排除jar 中的RedissonConfig.class。

    @ComponentScan(basePackages = {"com.xx.xx.*"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {RedissonConfig.class}))

    或者

    @SpringBootApplication(scanBasePackages = {
        "org.activiti.rest",
        "org.activiti.app.conf",
        "org.activiti.app.repository",
        "org.activiti.app.service",
        "org.activiti.app.security",
        "org.activiti.app.model.component",
        "org.activiti.engine"},
        exclude = {
            //org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
            //org.activiti.spring.boot.SecurityAutoConfiguration.class,
            HibernateJpaAutoConfiguration.class,
            JpaRepositoriesAutoConfiguration.class, //禁止springboot自动加载持久化bean
            org.activiti.spring.boot.JpaProcessEngineAutoConfiguration.class})
    @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
        DatabaseConfiguration.class}))

     @ComponentScan注解。扫描或解析的bean只能是Spring内部所定义的,比如@Component、@Service、@Controller或@Repository。如果有一些自定义的注解,比如@Consumer、这个注解修饰的类是不会被扫描到的。这个时候我们就得自定义扫描器完成这个操作。

    配置文件中使用的:component-scan标签底层使用ClassPathBeanDefinitionScanner这个类完成扫描工作的。@ComponentScan注解配合@Configuration注解使用,底层使用ComponentScanAnnotationParser解析器完成解析工作。

    spring boot 启动报错

    Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!

    估计是跟多个数据源有关,改成如下这样就可以了
     

    @SpringBootApplication  
    @EnableAutoConfiguration(exclude={  
          JpaRepositoriesAutoConfiguration.class//禁止springboot自动加载持久化bean
            })  
    @ImportResource({"classpath:spring-servlet.xml"})  
    public class JzApplication {  
          
        public static void main(String[] args) throws Exception {  
            ApplicationContext ctx = SpringApplication.run(JzApplication .class,args);  
        }  
    } 

     

    目录

    Spring注解开发-全面解析常用注解使用方法


    github位置:https://github.com/WillVi/Spring-Annotation/

    1. @Configuration

    ​ @Configuration //配置注解类似 applicationcontext.xml 只是将xml配置改为 注解方式进行

    2. @ComponentScan

    进行包扫描会根据注解进行注册组件,value="包名"

    @ComponentScan(value="cn.willvi")

    ### FilterType

    • ANNOTATION 通过注解类型 列如 @Controller为Controller.class @Service 为 Service.class
    • ASSIGNABLE_TYPE, 一组具体类 例如PersonController.class
    • ASPECTJ, 一组表达式,使用Aspectj表达式命中类
    • REGEX 一组表达式,使用正则命中类
    • CUSTOM 自定义的TypeFilter.

    excludeFilters

    ​ excludeFIlters = Filter[] 根据规则排除组件

    @ComponentScan(value="cn.willvi",excludeFilters= {
            //根据注解排除注解类型为@Controller
            @Filter(type=FilterType.ANNOTATION,value= {Controller.class}),
            @Filter(type=FilterType.ASSIGNABLE_TYPE,value= {IncludeConfig.class,MainConfig.class}),
    })

    includeFilters

    ​ includeFIlters = Filter[] 根据规则只包含哪些组件(ps:useDefaultFilters设置为false

    @ComponentScan(value="cn.willvi",includeFilters= {
            //根据注解类型扫描注解类型为@Controller的类
            @Filter(type=FilterType.ANNOTATION,value= {Controller.class})
    },useDefaultFilters=false)

    使用自定义TypeFilter

    ​ 当过滤有特殊要求时,可以实现TypeFilter来进行自定的过滤规则

    自定义TypeFilter:

    public class CustomTypeFilter implements TypeFilter {
        /**
         * metadataReader the metadata reader for the target class 读取当前扫描类的信息
         * metadataReaderFactory a factory for obtaining metadata readers
         * for other classes (such as superclasses and interfaces) 获取其他类的信息
         */
        public boolean match(MetadataReader reader, MetadataReaderFactory factory) throws IOException {
            //获取当前扫描类信息
            ClassMetadata classMetadata = reader.getClassMetadata();
            //获取当前注解信息
            AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
            //获取当前类资源(类路径)
            Resource resource = reader.getResource();
            String className = classMetadata.getClassName();
            System.out.println("----->"+className);
            if(className.contains("PersonService")) {
                return true;
            }
            return false;
        }
    }

    使用:

    //自定义过滤组件
    @ComponentScan(value="cn.willvi",includeFilters= {
            @Filter(type=FilterType.CUSTOM,value= {CustomTypeFilter.class})
    },useDefaultFilters=false)
    //或者
    //自定义过滤组件
    @ComponentScan(value="cn.willvi",excludeFilters= {
            @Filter(type=FilterType.CUSTOM,value= {CustomTypeFilter.class})})

    3. @Bean

    ​ 注册bean与spring 的xml配置异曲同工之妙只是将xml配置转换为注解

      <bean id="person" class="cn.willvi.bean.Person"  scope="prototype" >
            <property name="age" value="23"></property>
            <property name="name" value="willvi"></property>
        </bean>

    @Scope

    ​ 在 Spring IoC 容器是指其创建的 Bean 对象相对于其他 Bean 对象的请求可见范围。

    • singleton单例模式 全局有且仅有一个实例

    • prototype原型模式 每次获取Bean的时候会有一个新的实例

    • request 每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效

    • session session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效

    • global session global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。

      以上5个一般只用第一个和第二个

    原型模式使用:

        @Bean
        @Scope("prototype")
        public Person person() {
            return new Person("willvi",23);
        }

    验证:

            ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class);
            Person person = (Person) ioc.getBean("personScope");
            Person person1 = (Person) ioc.getBean("personScope");
            //返回true说明为单例
            System.out.println(person==person1);

    @Lazy

    ​ 懒加载。当Scope为单例模式时,当容器被初始化时就会被实例化。

    ​ 当有@Lazy时,在容器初始化时不会被实例化,在获取实例时才会被初始化

    单例模式懒加载使用

    @Bean
        @Scope
        @Lazy //去掉和加上看输出结果
        public Person person() {
            System.out.println("bean初始化");
            return new Person("willvi",23);
        }

    验证:

        ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("容器初始化完成");
        Person person = (Person) ioc.getBean("personScope");

     参考:

    https://blog.csdn.net/u014252478/article/details/83831224

    正因为当初对未来做了太多的憧憬,所以对现在的自己尤其失望。生命中曾经有过的所有灿烂,终究都需要用寂寞来偿还。
  • 相关阅读:
    ORACLE 11g RACRAC DG Duplicate 搭建(生产操作文档)
    oracle跨数据库
    Linux查看网络流量
    数据库性能监控脚本
    三节点DG环境主库单机转RAC(DG主备切换)
    Oracle dblink介绍
    script 加载失败触发onerror事件
    流程图
    The State of JavaScript 2019
    throw , console.error, new Error
  • 原文地址:https://www.cnblogs.com/candlia/p/11919997.html
Copyright © 2020-2023  润新知