带你了解Spring-IOC注解开发
一、背景-顺应历史潮流
随着Springboot开发的流行,我们也开始频繁的使用注解开发,今天理一下常见的Spring-IOC注解。以下代码经过我亲测,有不对的地方望指点纠正
二、使用与测试
测试代码的结构:
在开始之前先来一波以前利用xml配置文件创建注入的方法:
新建实体类Person.class
public class Person {private String name;private Integer age;public Person(String name, Integer age) {super();this.name = name;this.age = age;}public Person() {super();}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String toString() {return "Person [name=" + name + ", age=" + age + "]";}}
新建beans.xml文件
<bean id="person" class="com.lvbl.beans.Person"><property name="age" value="23"></property><property name="name" value="lvbl"></property></bean>
测试代码为:
public class MainTest {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");Person bean = (Person) applicationContext.getBean("person");System.out.println(bean);}}
测试完成:输出如图
第一种方法完结,没有问题,现在我们进入主题,使用注解配置
新建配置类:MainConfig.class
public class MainConfig {/*** 使用配置类替换xml文件注入时,返回类型即是方法的返回类型,id默认是方法名* Bean注解后跟着的别名即是id名,不取默认的方法名* @return*/public Person superMan() {return new Person("demo", 2);}}
!注意:@Bean注解效果跟xml文件的bean标签效果相同,如果不指定,则返回类型为方法的返回类型,而id呢?默认值是方法名,若指定,则@Bean后面跟别名
测试代码:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);//用返回类型获取beanPerson bean = applicationContext.getBean(Person.class);System.out.println("使用返回类型获取" + bean);//使用id获取Person bean1 = (Person) applicationContext.getBean("person");System.out.println("使用id名获取" + bean1);String[] namesForType = applicationContext.getBeanNamesForType(Person.class);for (String name : namesForType) {System.out.println("id:" + name);}
输出结果:
那么,在xml文件中的bean标签下可以配置包扫描,用注解当然也可以啊,
@ComponentScan注解就是用来解决包扫描问题的
},useDefaultFilters = false)
将配置文件改成以上模样
@ComponentScan(value="com.lvbl"):扫描该包下所有的类,在JDK1.8的时候还可以写多个@ComponentScan
includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
useDefaultFilters = false:关闭默认开关
类似的规则还有:
excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件FilterType.ANNOTATION:按照注解FilterType.ASSIGNABLE_TYPE:按照给定的类型;FilterType.ASPECTJ:使用ASPECTJ表达式FilterType.REGEX:使用正则指定FilterType.CUSTOM:使用自定义规则
Spring默认创建的bean都为单实例,无论从容器获取多少次都相等,使用@Scope("prototype")注解可配置为多例,有时候面试可能会被问到容器创建与bean创建的先后顺序,如下
单实例的情况下:IOC容器在启动的时候会调用方法创建对象放入容器中,之后的每次获取都是从容器中获取;
多实例的情况下:当IOC容器创建时并不会去调用方法创建对象,而是在调用对象时才会调用方法创建,并且每次调用都会执行一遍
由此还可以引出懒加载的概念,懒加载针对的是单实例的情况,使用该注解后,IOC容器初始化后并不会创建bean,而是在调用的时候才创建,这是细节,一定得记住
还有一个自定义规则的注解:@Conditional //按条件创建对象
使用场景如:根据不同的操作系统创建不同的对象
新建LinuxCondition.class,必须实现Condition父类
public class LinuxCondition implements Condition {/**获取我的电脑操作系统的信息* ConditionContext:判断条件能使用的上下文(环境)* AnnotatedTypeMetadata:注释信息*/public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//获取当前环境信息Environment environment = context.getEnvironment();String property = environment.getProperty("os.name");if(property.contains("linux")){return true;}return false;}}
新建WindowsCondition.class
public class WindowsCondition implements Condition{/*** ConditionContext:判断条件能使用的上下文(环境)* AnnotatedTypeMetadata:注释信息*/public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//获取当前环境信息Environment environment = context.getEnvironment();String property = environment.getProperty("os.name");if(property.contains("Windows")){return true;}return false;}}
修改配置类,在@Bean注解上加上@Configuration
public class MainConfig2 {public Person superMan() {return new Person("person", 1);}public Person zhangsang() {return new Person("linux", 1);}public Person lisi() {return new Person("Windows", 1);}}
测试代码和测试结果如图:
很明显,由于我的操作系统为Windows7,所以Linux的对象并未创建
提示:该注解还可以放在类上,只是作用域不用,如果放在类上,则该类所以的bean只有在符合条件时才会被创建
快速注入:@Import,该注解可以快速注入,这种注入方式的id为全类名,在配置类上加上@Import(Book.class),当然,提前新建Book类,测试结果如图
测试代码链接:https://pan.baidu.com/s/1P9n8p3lfB8yPsLNZ_5jyDw
提取码:kdla
————很感谢你看到这里,如果你也喜欢,可以点击分享哦——————
这是我的微信公众号,里面有三千多G的学习资料,从软件到实战项目,剑指Offer面试题集都分类打包好了,扫码关注就能无套路免费领取哦!

浙公网安备 33010602011771号