spring注解驱动开发(一)
初步介绍
spring注解驱动开发随着springboot这个简洁化开发,约定大于配置的大环境下,spring注解版知识点使用的也开始越来越多,所以我已经学习了基础springboot之后果断停止,开始学习spring注解驱动开发,下面是我总结的一些注解知识,这个页面会一直更新,用于以后的查阅
1、@Configurable注解以及@Bean的使用
Configurable表示这个一个配置类,代替原先xml配置
之前我们用xml做DI(依赖注入),现在我们可以通过class的方式来声明一个配置类
xml配置1
2
3
4
5
6
7
8
9
10
11
<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-2.0.xsd">
<bean id="person" class="cn.itcast.pojo.Person">
<property name="username" value="lmx"></property>
<property name="password" value="123"></property>
</bean>
</beans>
现在可以使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package cn.itcast.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import cn.itcast.pojo.Person;
public class MyConfig {
"lmx") (name=
public Person person() {
return new Person("lmz","456");
}
}
上面的bean代替旧的即<bean/>
可以实现向容器注册组件,其中bean的name属性指的是注册组件在容器中的ID,默认是方法名作为组件的ID
然后通过下面的测试,果然简单有效,赞!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package cn.itcast.test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.config.MyConfig;
import cn.itcast.pojo.Person;
public class MainTest {
public static void main(String[] args) {
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
// Person person = (Person)applicationContext.getBean("person");
// System.out.println("姓名:"+person.getUsername());
// System.out.println("密码:"+person.getPassword());
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Person bean = context.getBean(Person.class);
System.out.println("姓名:"+bean.getUsername());
System.out.println("密码:"+bean.getPassword());
String[] beanNamesForType = context.getBeanNamesForType(Person.class);
for (String string : beanNamesForType) {
System.out.println(string);
}
}
}
2、@ComponentScan包扫描注解
context:component-scan主要用于扫描对应包下面的注解到容器中,一般有以下注解
- @Controller
- @Service
- @Repository
- @Component
对应的xml配置
<context:component-scan base-package="cn.itcast"/>’
用class类文件的方式,把下面配置配在config文件的上面,这样可以实现包扫描
@ComponentScan(basePackages= {“cn.itcast”})’
@excludeFilters
可以除去不想扫描进容器的注解1
2
3
4"cn.itcast"},excludeFilters= { (basePackages= {
(type=FilterType.ANNOTATION,classes=Controller.class),
(type=FilterType.ANNOTATION,classes=Service.class)
})
use-default-filters
这个语句主要是关闭默认扫描对应包下面的所有注解
@includeFilters
中要把use-default-filters
设置成false
xml中这样写
<context:component-scan base-package="cn.itcast" use-default-filters="false" />
使用class文件这样写就ok了1
2
3
4"cn.itcast"},includeFilters = { (basePackages = {
(type=FilterType.ANNOTATION,classes=Controller.class),
(type=FilterType.ANNOTATION,classes=Service.class)
},useDefaultFilters = false)
由于java8以上才有@Repeatable这个注解,表示可以注解重复,但是java8以下不支持,所以我们要做兼容性
有一个注解@ComponentScans,可以包含多个@ComponentScan
3、 @Scope注解
扫描到容器的默认是单实例的我们可以通过scope改变默认值
xml中我们是这样来表示scope的1
2
3
4<bean id="person" class="cn.itcast.pojo.Person" scope="prototype">
<property name="username" value="lmx"></property>
<property name="password" value="123"></property>
</bean>
class类方式在@Bean注解上添加@Scope
注: 单实例是ioc容器启动的时候就就把对象创建放进容器了,但多实例是什么时候调用就什么时候创建
例如:@Scope('prototype')
这个表明扫描进容器的组件是多实例的,当然我们也可以使用@Scope('singleton')
或者不写,可以实现单实例1
2
3
4
5"SCOPE_PROTOTYPE") (value=
"lmx") (name=
public Person person() {
return new Person("lmz","456");
}
4、 @Lazy懒加载的使用
把这个注解放在@Bean的上面表示懒加载,即IOC容器启动的时候创建,什么时候使用什么时候创建
注:这个属性主要针对的是单实例的
5、 @Conditional条件注解的使用
这个注解在springboot的底层源码用的最多,所以有必要好好深挖一下
我写了一个demo1
2
3
4
5
6
7
8
9
10
11 (WindowsCondition.class)
"bill") (name=
public Person person01() {
return new Person("Bill Gates","123");
}
(LinuxCondition.class)
"linus") (name=
public Person person02() {
return new Person("linus","456");
}
分别创建WindowsCondition、LinuxCondition,都要实现Condition接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public class LinuxCondition implements Condition{
//参数 context 上下文环境
// 参数 metadata 当前注释此注解的信息
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// //获得ioc使用的beanfactory
// ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//
// //获取类加载器
// ClassLoader classLoader = context.getClassLoader();
//
// //获取bean定义的注册类
// BeanDefinitionRegistry registry = context.getRegistry();
// //判断对应的bean是不是在ioc容器中已经存在
// boolean isExist = registry.containsBeanDefinition("lmx");
//
//获取当前系统环境信息
Environment environment = context.getEnvironment();
//获取操作系统属性
String property = environment.getProperty("os.name");
if(property.contains("Linux"))
return true;
return false;
}
}
1 | public class WindowsCondition implements Condition{ |
然后做测试1
2
3
4
5AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
String[] strings = context.getBeanNamesForType(Person.class);
for (String string : strings) {
System.out.println(string);
}
结果:由于我的系统是Windows,所以ioc容器中注册的组件id是 bill