Spring注解开发
Posted -王二毛-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring注解开发相关的知识,希望对你有一定的参考价值。
一、注入组件方式一:使用@Configuration和@Bean
1.1、对照组:通过原始xml方式给容器注入组件
、
bean:Person
beans.xml
<?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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id= "person" class="com.atguigu.bean.Person">
<property name="age" value="18"></property>
<property name="name" value="zhangsan"></property>
</bean>
</beans>
测试类MainTest.java
public class MainTest
public static void main(String[] args)
//使用ClassPathXmlApplicationContext根据名称加载解析类路径下的beans.xml文件,返回bean容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//从容器中,根据名称获取bean实例对象
Person bean =(Person) applicationContext.getBean("person");
System.out.println(bean);
结果
1.2、使用@Configuration和@Bean注解
配置类MainConfig.java
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id,此时方法名不再作为id
public Person person01()
return new Person("ermao",20);
测试类MainTest.java
public class MainTest
public static void main(String[] args)
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//从容器中,通过类型获取bean
Person bean =(Person) applicationContext.getBean(Person.class);
System.out.println(bean);
//查看Person类型的组件在容器中的名字是什么
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name : namesForType)
System.out.println(name);
1.3、@ComponentScan自动扫描组件和配置扫描规则
1.3.1、对照组:通过原始xml结合<context:component-scan>
方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 包扫描、只要标注了@Controller、@Service、@Repository,@Component都会被扫描 -->
<context:component-scan base-package="com.atguigu"></context:component-scan>
<bean id= "person" class="com.atguigu.bean.Person">
<property name="age" value="18"></property>
<property name="name" value="zhangsan"></property>
</bean>
</beans>
1.3.2、使用 @ComponentScan注解方式
MainConfig.java
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.atguigu")//配置包扫描
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id
public Person person01()
return new Person("ermao",20);
测试
public class IOCTest
@Test
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//获取所有的bean,包括自定义和系统的所有bean
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames)
System.out.println(name);
结果
1.3.3、通过对@ComponentScan注解设置参数配置扫描规则
1)、excludeFilters排除指定的,其他都扫描
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.atguigu",excludeFilters =
@Filter(type = FilterType.ANNOTATION,classes = Controller.class,Service.class)
)//配置包扫描
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id
public Person person01()
return new Person("ermao",20);
2)、includeFilters只扫描指定的组件,加到容器中
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.atguigu",includeFilters =
@Filter(type = FilterType.ANNOTATION,classes = Controller.class,Service.class)
,useDefaultFilters = false)//配置包扫描
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id
public Person person01()
return new Person("ermao",20);
3)、自定义Filter指定配置规则
自定义配置规则类和定义配置规则
MyTypeFilter.java
public class MyTypeFilter implements TypeFilter
// metadataReader:读取到的当前正在扫描的类的信息.
// metadataReaderFactory :可以获取到其他任何类信息的
@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("er"))
return true;
return false;
使用自定义的配置规则
MainConfig.java
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.atguigu",includeFilters =
//根据注解配置
// @Filter(type = FilterType.ANNOTATION,classes = Controller.class,Service.class),
//根据类型配置
// @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = BookService.class),
//自定义规则
@Filter(type = FilterType.CUSTOM,classes = MyTypeFilter.class)
,useDefaultFilters = false)//配置包扫描
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id
public Person person01()
return new Person("ermao",20,"二毛");
测试
@Test
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//获取所有的bean
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames)
System.out.println(name);
//关闭容器
applicationContext.close();
二、注入组件方式二:使用@Import快速注入
2.1、直接快速导入
快速导入组件
测试
@Test
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//获取bean
String[] namesForType = applicationContext.getBeanDefinitionNames();
for (String name : namesForType)
System.out.println(name);
//关闭容器
applicationContext.close();
结果
2.2、通过ImportSelector条件快速导入
将需要快速导入的组件放到一个ImportSelector类中,封装成数组返回
封装
MyImportSelector.java
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector
//返回值,就是到导入到容器中的组件全类名
//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata)
//importingClassMetadata
//方法不要返回null值
return new String[]"com.atguigu.bean.Blue","com.atguigu.bean.Yellow";
注册
测试
@Tescst
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//获取bean
String[] namesForType = applicationContext.getBeanDefinitionNames();
for (String name : namesForType)
System.out.println(name);
//关闭容器
applicationContext.close();
2.3、通过ImportBeanDefinitionRegistrar:手动注册bean到容器中
MyImportBeanDefinitionRegistrar.java
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar
/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所有需要添加到容器中的bean;调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
//判断是否有
boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
if(definition && definition2)
//指定Bean定义信息;(Bean的类型,Bean。。。)
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个Bean,指定bean名
registry.registerBeanDefinition("rainBow", beanDefinition);
三、注入组件方式三:使用FactoryBean注入
创建一个Spring定义的FactoryBean
ColorFactoryBean.java
public class ColorFactoryBean implements FactoryBean<Color>
//返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception
System.out.println("ColorFactoryBean...getObject...");
return new Color();
@Override
public Class<?> getObjectType()
return Color.class;
//是单例?
//true:这个bean是单实例,在容器中保存一份
//false:多实例,每次获取都会创建一个新的bean;
@Override
public boolean isSingleton()
return false;
注册
MainConfig.java
测试
@Test
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//工厂Bean获取的是调用getObject创建的对象
Object bean2 = applicationContext.getBean("colorFactoryBean");
Object bean3 = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型:"+bean2.getClass());
System.out.println(bean2 == bean3);
Object bean4 = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean4.getClass());
//关闭容器
applicationContext.close();
结果
四、@Scope设置组件作用域
4.1、对照组:相对于xml文件的scope属性
4.2、使用@Scope注解方式
设置
MainConfig.java
//创建配置,这个配置类等同于beans.xml
@Configuration //告诉Spring这是一个配置类
/*
* 默认是单实例
*
* prototype:多实例的:多实例的: ioc容器启动并不会去调用方法创建对象放在容器中。
每次获取的时候才会调用方法创建对象;
* singleton:单实例的(默认值): ioc容器启动会调用方法创建对象放到io.c容器中。
以后每次获取就是直接从容器中拿
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*/
@Scope("singleton")
public class MainConfig
//给容器添加一个bean,类型为返回值的类型,id默认是用方法名作为id
@Bean("person")//指定id
public Person person01()
return new Person("ermao",20,"二毛");
测试
@Test
public void test01()
//使用AnnotationConfigApplicationContext加载配置类,返回IOC容器
//如果是单实例:初始化ioc容器启动会调用方法创建对象放到io.c容器中。以后每次获取就是直接从容器中拿
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
//通过类型获取bean
Person bean1 =(Person) applicationContext.getBean("person");//多实例,每次获取的时候才会调用方法创建对象
Person bean2 =(Person) applicationContext.getBean("person");
System.out.println(bean1 == bean2);
//关闭容器
applicationContext.close();
结果
五、@Lazy组件懒加载
基于spring注解AOP的异常处理