spring注解驱动(组件注册):创建工程,组件注册,自动扫描组件

创建工程

首先创建好Maven工程,将spring context的依赖导入进来
spring context的依赖去这个网站查找就行,输入spring context就能找到
选个稳定点的版本,将依赖导入进去就可以了

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>4.3.12.RELEASE</version>
	</dependency>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组件注册

以前的方式注入

首先写一个spring的配置文件之类的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="person" class="jane.bean.Person">
		<property name="name" value="张三"></property>
		<property name="age" value="18"></property>
	</bean>
</beans>

当然有对应的POJO

package jane.bean;

public class Person
{
    
    
	private String name;
	private Integer age;

主程序类,结果是能成功的

package jane;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import jane.bean.Person;

public class Test
{
    
    
	public static void main(String[] args)
	{
    
    
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
		Person bean = ac.getBean(Person.class);
		System.out.println(bean);
	}
}

注解版的方式

package jane.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import jane.bean.Person;

/*
 * 现在编写的是一个配置类,作用和之前的xml配置文件相同
 * 只不过是现在是Java代码配置,之前是xml文件配置
 * 首先得有注解@Configuration,告诉spring这是一个配置类
 * 和之前告诉spring这个xml文件是一个配置文件一样
 * 
 * @Bean注解就是给容器中注册一个bean,类型是返回值的类型,id默认是用方法名作为id
 * 作用和之前的<bean>标签效果是一样的
 * 如果想修改默认的id就在@Bean(value = "JanePerson")里面加上value的值
 */
@Configuration
public class MyConfig
{
    
    
	@Bean
	public Person person()
	{
    
    
		return new Person("李四", 23);
	}
}

如何使用

package jane;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import jane.bean.Person;
import jane.config.MyConfig;

public class Test
{
    
    
	public static void main(String[] args)
	{
    
    
//		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//		Person bean = ac.getBean(Person.class);
//		System.out.println(bean);
		
		//由名知义,这是一个根据配置类加载的容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
		Person bean = applicationContext.getBean(Person.class);
		System.out.println(bean);
		
		String[] strings = applicationContext.getBeanNamesForType(Person.class);
		for (String string : strings)
		{
    
    
			System.out.println(string);
		}
	}
}

自动扫描组件

以前的写法

	<!-- 包扫描中,只要标注了@Controller,@Service,@Repository,@Component
		这四个注解都会被扫描进去,这里只是写出全部可以写的,正常不这样使用
	 -->
	<context:component-scan base-package="jane" 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>

注解版的写法

package jane.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import jane.bean.Person;

@Configuration
/*
 * @ComponentScan(value = "jane")
 * value:指定要扫描的包,点进去原码查看value可以指定的是数组
 * excludeFilters =  Filter[] excludeFilters() default {};查看原码,里面写的是Filter数组,
 * 					@Filter点进原码查看,可以写type(过滤类型),classes(过滤的类),pattern(),value
 * 
 * includeFilters =  Filter[],和上面的一样,只不过也是要配置不适用默认的规则,useDefaultFilters = false
 */
@ComponentScan(value = "jane",
//				excludeFilters = {
    
    
//						@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
//								}
				includeFilters = {
    
    
						@Filter(type = FilterType.ANNOTATION,classes = {
    
    Controller.class,Service.class})
				},
				useDefaultFilters = false
				)
//如果想写多个@ComponentScan,如果是jdk8的话,是可以直接写多个的,不是也可以使用@ComponentScans
//将你要写的多个@ComponentScan放在value里面就行
//@ComponentScans
//(
//		value = 
//		{
    
    
//			@ComponentScan(value = "jane",
//					includeFilters = {
    
    
//							@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
//					},
//					useDefaultFilters = false
//					)
//		}
//)
public class MyConfig
{
    
    
	@Bean(value = "JanePerson")
	public Person person()
	{
    
    
		return new Person("李四", 23);
	}
}

@Filter的type = FilterType.

 * @Filter的type
 * FilterType.ANNOTATION		按照注解进行过滤
 * FilterType.ASSIGNABLE_TYPE	按照自己给定的类型来过滤
 * FilterType.ASPECTJ			使用ASPECTJ表达式过滤
 * FilterType.REGEX				使用正则指定
 * FilterType.CUSTOM			使用自定义规则

例如
includeFilters = {
    
    
			@Filter(type = FilterType.ANNOTATION,classes = {
    
    Controller.class,Service.class}),
			@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {
    
    MyConfig.class}),
			@Filter(type = FilterType.CUSTOM,classes = {
    
    MyTypeFilter.class})
	},
	useDefaultFilters = false

其中的自定义规则需要写自定义类的规则实现TypeFilter接口

	/** Filter candidates using a given custom
	 * {@link org.springframework.core.type.filter.TypeFilter} implementation.
	 */
	CUSTOM

自定义TypeFilter的实现类

package jane.config;

import java.io.IOException;

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;

public class MyTypeFilter implements TypeFilter
{
    
    
	/*
	 * metadataReader:
	 * @param metadataReader the metadata reader for the target class
	 * 读取到的目标类的信息
	 * 
	 * metadataReaderFactory:
	 * @param metadataReaderFactory a factory for obtaining metadata readers
	 * for other classes (such as superclasses and interfaces)
	 * 可以获取其他任何类(父类或者接口)的信息
	 */
	@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();
		System.out.println("当前类的类名=========="+className);
		
		if(className.contains("service"))
		{
    
    
			return true;
		}
		return false;
	}

}

在测试里面进行测试

package jane;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import jane.config.MyConfig;

public class IOCTest
{
    
    
	@Test
	public void test1()
	{
    
    
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
		String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
		for (String string : beanDefinitionNames)
		{
    
    
			System.out.println(string);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/107865576