在学习spring中的注解开发之前,必须了解java中的反射和注解:
当一个项目很大的时候,xml 文件就会有很多,配置起来就稍微有点麻烦,所以,可以使用注解来代替在xml的相关配置。 用在类上,指明这个类是配置类,相当于是一个只有名称空间的xml文件,有了配置类,就可以不用写xml文件了。 用在方法上,给IOC容器中注册一个bean,id 默认为方法名,也可以使用value属性指定,类型是方法的返回值类型。相当于在xml文件中写 用在配置类上,开启包扫描,开启之后,类只要标注了@Controller、@Service、@repository、@Componmente @Filter这个注解中,type的类型是FilterType枚举类,枚举类中有以下几个值 自定义过滤规则,就是写一个类,实现FilterType接口,实现match方法(过滤规则),当扫描一个类时,会执行match方法,如果返回true,表示,符合规则,将这个类在IOC容器中注册,返回false,不在容器中注册。 自定义规则(只要含有 “er” 的类) 指定bean的作用范围,有如下四个属性: 懒加载,容器启动时,不创建对象,获取时才会创建,只有当是bean是单例的(singleton)时才有用 用在方法上,按照一定条件进行判断,满足条件给容器注册bean,注意需要和@Bean一起使用。也可以把这个注解放在类上,类中的bean满足条件才可以在容器中注册 自定义条件类 给容器中注册组件(bean),前面已经写了两种: @Import(类名.class) 快速给容器中导入一个组件,id为类的全路径名,用在类上,属性为class类型的数组 自定义选择器类 注册类 使用spring提供的FactoryBean(工厂bean)也可以给容器注册bean。FactoryBean 是一个接口,里面有三个方法,getObject,获取对象,getObjectType,获取对象类型,isSingleton,是否是单例模式。定义一个类实现FactoryBean接口,实现上面三个方法,然后在配置类中,使用@Bean注解来注册这个类,需要注意的是,通过getBean方法获取的是在getObject中生成的对象,而不是FactoryBean对象,可以在name前面加一个“&”获取FactoryBean 对象。 配置类 bean创建—初始化—销毁的过程 我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用自定义的初始化和销毁方法。 BeanPostProcessor 原理 Spring底层对 BeanPostProcessor 的使用 xml中是在标签下使用进行属性注入的,可以使用@Value注解代替,@Value中,可以写: 自动注入,默认优先根据类型在容器中找对应的组件,将组件赋给@Autowired下的属性,如果容器中有多个相同类型的组件,会将属性名作为id在容器中查找组件。 如果容器中没有相同类型的bean或者指定id的bean,会报错,可以修改required属性为false(默认为true),就不报错了。 @Resouce 和 @Inject 都可以自动注入,@Resource(name=””) 是根据bean的id自动注入的,不支持@Primary来指定首选bean。使用@Inject 要导入javax.inject包,注解里没有属性。这两个注解式java规范的,@Autowired是spring定义的。 自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx),自定义组件类可以实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware,把Spring底层一些组件注入到自定义的Bean中; 指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件 参考:文章目录
1. 组件添加相关注解
1.1 @Configuration
1.2 @Bean
<bean id=" " class=" "/></bean>
。如果方法中有参数,参数默认从容器中获取。
`@//表示这个类是配置类,代替xml文件 @Configuration public class MainConfig { @Bean //在IOC容器中注册bean,类型是返回值类型,id默认是方法名 public Person person(){ return new Person("张三",20); } }
1.3 @ComponentScan
这四个注解中的任何一个,都会在容器中注册,相当于在xml文件中使用<context:componment-scan value=" ">
@ComponentScan(value="ewen", excludeFilters = { 排除@Repository注解 @Filter(type=FilterType.ANNOTATION,classes={Repository.class}) })
useDefaultFilters=false
(@CoponentScan的属性),来禁用默认的过滤规则,默认使用的是不扫描哪些些组件@ComponentScan(value="ewen", includeFilters ={ //只要@Service注解 @Filter(type=FilterType.ANNOTATION, classes={Service.class, Repository.class}) }, useDefaultFilters = false)
@ComponentScan(value="ewen", includeFilters = { @Filter(type=FilterType.CUSTOM, classes={MyTypeFilter.class}) } , useDefaultFilters = false )
public class MyTypeFilter implements TypeFilter { /** * @param metadataReader:读取到的当前正在扫描的类信息 * @param metadataReaderFactory:可以获取到其他类的任何信息 * @return 当进行包扫描时,使用自定义过滤规则,扫描到的类来与这个方法中定义的规则匹配 * 如果返回true,代表符合规则,将这个类注入到容器中,返回false,代表不符合规则 * @throws IOException */ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获得当前正在扫描类的注解信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前正在扫描的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //获取当前正在扫描类的路径 Resource resource = metadataReader.getResource(); String name = classMetadata.getClassName(); if(name.contains("er")){ return true; } return false; } }
1.4 @Scope
1.5 @Lazy
1.6 @Conditional
需要定义一个条件类,实现Condition接口,实现match方法,如果这个方法返回true,则符合条件,注册bean //如果是Windows操作系统,给容器中注册bill @Conditional(WindowsCondition.class) @Bean public Person person01(){ return new Person("bill", 60); }
//判断当前操作系统是不是Windows public class WindowsCondition implements Condition { /** * * @param conditionContext:判断条件能使用的上下文环境 * @param annotatedTypeMetadata:注释信息 * @return 如果返回true,代表符合条件,返回false,表示不符合条件 */ public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { /*通过conditionContext可以获得很多有用的信息, 可以使用这些信息,来设置很多条件 //1.获取IOC使用的工厂BeanFactory ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); //2.获取类加载器 ClassLoader classLoader = conditionContext.getClassLoader(); //4.获取bean定义的注册类,通过这个类可以注册、查询、移除IOC容器中的bean BeanDefinitionRegistry registry = conditionContext.getRegistry(); */ //3. 获取运行时的环境信息 Environment environment = conditionContext.getEnvironment(); //获取当前的操作系统名字 String osName = environment.getProperty("os.name"); //判断当前操作系统是不是Windows 10 if(osName.contains("Windows")){ return true; } return false; } }
1.7 @Import
比如,在容器中注册Color、Red类@Configuration //@Import:快速在容器中注册组件,id为类的全路径名 @Import({Color.class, Red.class}) public class MainConfig02 { 。。。}
@Configuration /* @Import:快速在容器中注册组件,id为类的全路径名 类名.class 选择器类.class */ @Import({Color.class, Red.class, MyImportSelector.class}) public class MainConfig02 { 。。。}
//选择器类 public class MyImportSelector implements ImportSelector { /** * @param importingClassMetadata:可以获得@Import标注的类的所有注解信息 * @return 返回一个String数组,里面要注册的bean的全路径名,id是全路径名 */ public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"ewen.bean.Blue"}; } }
@Configuration /* @Import:快速在容器中注册组件,id为类的全路径名 类名.class 选择器类.class:实现ImportSelector接口的类 注册类.class:实现ImportBeanDefinitionRegistrar接口的类 */ @Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig02 { 。。。}
//注册类 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** AnnotationMetadata:@Import标注类的注解信息 BeanDefinitionRegistry:bean的注册类,通过这个类,调用registerBeanDefinition方法 可以手动的在容器中注册bean。也可以用这个类中的方法进行查询、移除bean */ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //先判断IOC容器中是否有蓝色和红色,如果都有,就注册一个RainBow boolean b1 = registry.containsBeanDefinition("ewen.bean.Blue"); boolean b2 = registry.containsBeanDefinition("ewen.bean.Red"); if(b1 && b2){ //指定bean的定义信息(bean的类型、作用域等等) RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class); //指定bean的id registry.registerBeanDefinition("rainBow",beanDefinition); } } }
1.8 FactoryBean
//自定义的FactoryBean,通过这个FactoryBean来给容器注册Bean public class ColorFactoryBean implements FactoryBean<Color> { public Color getObject() throws Exception { return new Color(); } public Class<?> getObjectType() { return Color.class; } //返回true,是单例,返回false不是单例 public boolean isSingleton() { return true; } }
@Bean public ColorFactoryBean colorFactoryBean(){ return new ColorFactoryBean(); }
2. Bean 的声明周期
2.1 容器管理bean的生命周期
指定bean的初始化和销毁方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
postProcessorBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等都使用的是xxx BeanPostProcessor。3. 属性注入相关注解
3.1 @Value
3.2 @Autowired
@Autowired 还可以用在构造器、方法、参数上,参数默认从容器中获取。3.3 @Resouce 和 @Inject
3.4 XXXAware
xxxAware:底层使用xxxAwareProcessor, 如ApplicationContextAware ==》ApplicationContextAwareProcessor。在bean中获取applicationContext。//实现ApplicationContextAware接口,可以在Color类中获得applicationContext //实现BeanNameAware接口,可以获得bean的id //实现EmbeddedValueResolverAware接口,可以解析字符串 @Component public class Color implements ApplicationContextAware, BeanNameAware,EmbeddedValueResolverAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void setBeanName(String name) { System.out.println("bean 的name:" + name); } //StringValueResolver解析字符串 public void setEmbeddedValueResolver(StringValueResolver resolver) { String s = resolver.resolveStringValue("你好${os.name} #{18 * 20}"); System.out.println("解析的字符串:" + s); }
3.5 @Profile
比如,在tes环境下,将dataSourceTest注册到容器,开发dev环境下,将dataSourceDev注册到容器
Spring注解驱动教程
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算