创建工程
首先创建好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);
}
}
}