在使用xml方式配置时,咱们只须要在xml中配置以下代码:
java
<context:component-scan base-package="包名"></context:component-scan>
那么在java代码中使用以下四个注解,而且这些注解所在的包名是上面配置的包及其子包,那么spring会帮咱们把相应的bean加如到IOC容器中。spring
在注解的方式下如何实现呢?在咱们的配置类的上面加上以下注解便可
maven
@ComponentScan(value={"包名1","包名2"})
此时该注解指定的几个包名及其子包中若是有类被上面四个注解修饰,那么就会自动被注入到IOC容器中。 ide
注意:若是ComponentScan没有其它配置的化,默认扫描与其配置类相同的包。 测试
新建一个maven工程,添加以下依赖ui
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency>
一、BookControllerspa
package com.yefengyu.annotation.controller; import org.springframework.stereotype.Controller; @Controller public class BookController { }
二、BookService ssr
package com.yefengyu.annotation.service; import org.springframework.stereotype.Service; @Service public class BookService { }
三、BookRepository code
package com.yefengyu.annotation.repository; import org.springframework.stereotype.Repository; @Repository public class BookRepository { }
四、主配置类component
package com.yefengyu.annotation.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(value = "com.yefengyu.annotation") public class MainConfig { }
五、测试
public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } }
六、结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookRepository
bookService
结果打印出如上内容,说明上面三个注解的bean都被添加到容器中。
@ComponentScan除了value 属性以外,还有其余属性,其中比较经常使用的是以下两个:
他们的做用就是指定过滤规则。
一、指定规则
对于上面的代码,只须要修改主配置类中ComponentScan注解中的内容便可:
@ComponentScan(value = "com.yefengyu.annotation", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class)},useDefaultFilters = false)
上面的注解的含义是在com.yefengyu.annotation及其子包下面,将注解为Service的bean加入到容器中。注意useDefaultFilters 默认为true,表示使用默认的过滤规则:不过滤;若是须要指定规则,那么就须要将useDefaultFilters 设置为false。注意includeFilters 和useDefaultFilters 同时使用便可。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookService
二、排除规则
对于上面的代码,只须要修改主配置类中ComponentScan注解中的内容便可:
@ComponentScan(value = "com.yefengyu.annotation", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class)})
若是要排除某些规则,就要使用excludeFilters ,注意不须要使用useDefaultFilters ,默认便可。
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController bookRepository
上面注解的含义就是在com.yefengyu.annotation及其子包下面,将注解为Controller的bean排除容器以外。
三、FilterType的类型
自定义类型的使用方式:
package com.yefengyu.annotation; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; import java.io.IOException; public class MyTypeFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前类注解信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前扫描的类的信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //获取当前扫描类资源信息 Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); if (className.contains("er")) { return true; } return false; } }
实现TypeFilter接口,重写match方法,知足条件的则返回true.
而后指定扫描策略:
@ComponentScan(value = "com.yefengyu.annotation", excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)})
结果以下:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookRepository
将类中含有er的排除在外。
四、指定多个ComponentScan
一、在jdk8之后能够直接写多个ComponentScan
@ComponentScan(basePackages = "com.yefengyu.annotation1")
@ComponentScan(basePackages = "com.yefengyu.annotation2")
二、也可使用ComponentScans注解
@ComponentScans(value = { @ComponentScan(basePackages = "com.yefengyu.annotation1"), @ComponentScan(basePackages = "com.yefengyu.annotation2") })