包扫描方式
通常在Spring中我们需要将一些需要用到的类以bean的方式注册到容器中,而在Spring框架中,通常使用
- @Controller
- @Service
- @Component
- @Repository
要是这些注解生效,我们需要给项目加上包扫描策略,如果是配置文件的方式,我们需要加上如下的xml配置
<context:component-scan base-package="com.spring.spel" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!--两个属性,两者选择其中一个,否则会报错-->
<!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
</context:component-scan>
- base-backage:Spring会默认扫描该包以及下面的子包中被@Controller,@Service,@Component,@Repository修饰的类,同时将这些类加入到容器中。
- use-default-filters:是否使用默认的包扫描方式,默认是扫描@Controller,@Service,@Component,@Repository修饰的类
- exclude-filter:扫描不包括哪些
- type:类型,类型一般分为annotation,custom,assignable,aspect,regex
- include-filter:扫描包括哪些
如果是采用java注解的方式进行包扫描,则需要做如下配置
@Configuration
@ComponentScan(value = "com.spring",excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)
})
public class MainConfiguration {
}
@Bean
被@Bean修饰的方法,返回回来的类会以方法名为bean名称注册到容器中。或者我们可以直接在@Bean的属性中指定bean的名称。
package com.spring.config;
import com.spring.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
public class MainConfiguration {
/**
* 如果@Bean的value没有参数,
* 则以@Bean修饰的方法返回的bean名称以方法名为准,否则以value为准。
* @return
*/
@Bean
public Person person(){
return new Person("conjane",23);
}
@Bean
public Person person3(){
return new Person("conjane",23);
}
@Bean(value = "conjane")
public Person person4(){
return new Person("conjane",23);
}
}
测试类
@Test
public void testBeansInApplicationContext(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfiguration.class);
String[] beans = applicationContext.getBeanDefinitionNames();
for (String bean:beans){
System.out.println("=====>" + bean);
}
}
执行结果
=====>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
=====>mainConfiguration
=====>person
=====>person3
=====>conjane
@Import
采用@Import方式,是将全类名作为bean名称注册到容器中。
package com.spring.config;
import com.spring.bean.Person;
import com.spring.spel.User;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
@Configuration
@Import(value = {Person.class, User.class})
public class MainConfiguration {
/**
* 如果@Bean的value没有参数,
* 则以@Bean修饰的方法返回的bean名称以方法名为准,否则以value为准。
* @return
*/
@Bean
public Person person(){
return new Person("conjane",23);
}
@Bean
public Person person3(){
return new Person("conjane",23);
}
@Bean(value = "conjane")
public Person person4(){
return new Person("conjane",23);
}
}
测试结果
=====>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
=====>mainConfiguration
=====>com.spring.bean.Person
=====>com.spring.spel.User
=====>person
=====>person3
=====>conjane
ImportSelector
该方式需要实现ImportSelector接口,重写selectImports方法,该方法的参数类型是AnnotationMetadata,通过该参数可以获得有关修饰类的其他一些属性。
package com.spring.config;
import com.spring.bean.Person;
import com.spring.dao.MyImportSelector;
import com.spring.spel.User;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
@Configuration
@Import(value = {MyImportSelector.class})
@ComponentScan(value = "com.spring")
public class MainConfiguration {
/**
* 如果@Bean的value没有参数,
* 则以@Bean修饰的方法返回的bean名称以方法名为准,否则以value为准。
* @return
*/
@Bean
public Person person(){
return new Person("conjane",23);
}
@Bean
public Person person3(){
return new Person("conjane",23);
}
@Bean(value = "conjane")
public Person person4(){
return new Person("conjane",23);
}
}
package com.spring.dao;
import com.spring.bean.Person;
import com.spring.spel.User;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Set;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{Person.class.getName(), User.class.getName()};
}
}
测试结果
=====>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
=====>mainConfiguration
=====>personController
=====>personDao
=====>personService
=====>com.spring.bean.Person
=====>com.spring.spel.User
=====>person
=====>person3
=====>conjane
ImportBeanDefinitionRegistrar
这样的需要实现ImportBeanDefinitionRegistrar接口,重写registerBeanDefinitions该方法。
package com.spring.dao;
import com.spring.bean.Person;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyBeanDefinitionRegistar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
BeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
beanDefinitionRegistry.registerBeanDefinition("personconjane",beanDefinition);
}
}
配置类
package com.spring.config;
import com.spring.bean.Person;
import com.spring.dao.MyBeanDefinitionRegistar;
import com.spring.dao.MyImportSelector;
import com.spring.spel.User;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
@Configuration
@Import(value = {MyBeanDefinitionRegistar.class})
@ComponentScan(value = "com.spring")
public class MainConfiguration {
/**
* 如果@Bean的value没有参数,
* 则以@Bean修饰的方法返回的bean名称以方法名为准,否则以value为准。
* @return
*/
@Bean
public Person person(){
return new Person("conjane",23);
}
@Bean
public Person person3(){
return new Person("conjane",23);
}
@Bean(value = "conjane")
public Person person4(){
return new Person("conjane",23);
}
}
测试结果
=====>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
=====>mainConfiguration
=====>personController
=====>personDao
=====>personService
=====>person
=====>person3
=====>conjane
=====>personconjane