Spring常用注解(绝对经典)
1、需要导入的spring框架的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
2、@Configuration
设置类为配置类
3、AnnotationConfigApplicationContext
- 通过配置类获取上下文环境applicationContext
- 可以通过getBeanDefinitionNames()获得配置类中配置的各类Bean
- 也可以使用getBeanNamesForType()通过类型来获得bean的name(id)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String str : beanDefinitionNames) {
System.out.println(str);
}
4、@Bean
- 注册一个javaBean
- 默认用方法名作为Bean的id
- 使用AnnotationConfigApplicationContext的实例 通过getBean来获得这个Bean
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
5、@ComponentScan
为配置类开启组件扫描
- 放在配置类的上方,指定扫描的包路径如
@ComponentScan(value = "com.atguigu")
- 还可以使用excludeFilter来设置类扫描规则如包含、排除,excludeFilter需要设置为一个数组
排除
包含使用excludeFilter,并为其设置一个过滤数组,来指定需要过滤掉那些组件
@Configuration
@ComponentScan(value = "com.atguigu",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class} )
})
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
包含
包含使用includeFilter,包含里面需要设置使用默认规则为false
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class} )},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
还可以设置按给定类型过滤
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes ={Controller.class,Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
classes ={BookService.class})
},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
其他可以设置的过滤方式还可以有:
- 使用FilterType.ASPECTJ按照ASPECTJ表达式
- 使用FilterType.REGEX按照REGEX正则表达式
- 使用FilterType.CUSTOM按照自定义规则过滤(需要实现TypeFilter接口)
自定义过滤规则
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(resource);
System.out.println(className);
if(className.contains("er")){
return true;
}
return false;
}
}
设置自定义规则
@Configuration
@ComponentScan(value = "com.atguigu",includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,
classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class MainConfig {
@Bean
public Person person(){
return new Person("lisi",20);
}
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String str : beanDefinitionNames) {
System.out.println(str);
}
}
测试结果
测试规则打印内容
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/bean/Person.class]
com.atguigu.bean.Person
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/config/MyTypeFilter.class]
com.atguigu.config.MyTypeFilter
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/controller/BookController.class]
com.atguigu.controller.BookController
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/dao/BookDAO.class]
com.atguigu.dao.BookDAO
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/service/BookService.class]
com.atguigu.service.BookService
file [/Users/human/Desktop/Project/05SpringMVC/spring-annotation/target/classes/com/atguigu/test/MainTest.class]
com.atguigu.test.MainTest
测试类打印过滤结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
myTypeFilter
bookController
bookService
6、@Controller
将类配置为Controller类
7、@Service
将类配置为service类
8、@Repository
将类配置为dao操作的类
9、@Component
将类配置为通用类组件
10、@Scope
调整bean的作用域范围,默认单实例,可以修改为多实例
Bean是默认单实例的,通过指明prototype(多实例)和singleton(单实例)属性指明是否单实例
- prototype:多实例
- singleton:单实例
- request:同一次请求创建一个实例
- session:同一个session创建一个实例
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
//Bean是默认单实例的,通过指明prototype(多实例)和singleton(单实例)属性指明是是否单实例
//prototype:多实例
//singleton:单实例
//request:同一次请求创建一个实例
//session:同一个session创建一个实例
@Scope("prototype")
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
}
测试
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Object bean1 = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean1==bean2);
}
测试结果为false
11、@Lazy懒加载
实例默认在容器创建时立即加载
使用@Lazy后,当需要创建实例时才被加载
-
不使用懒加载
实体类构造函数
public Person(String name, Integer age) {
System.out.println("给容器添加Person对象");
this.name = name;
this.age = age;
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器已创建完成");
//没有获取类的代码,单实际上类的实例已经被加载进容器了
}
测试结果
给容器添加Person对象
容器已创建完成
- 使用懒加载
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
}
测试代码
@Test
public void testbeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器已创建完成");
Object bean1 = applicationContext.getBean("person");//这一句出现后才加载Person类
}
测试结果
给容器添加Person对象
容器已创建完成
12、@Conditional
- 按一定条件注册bean,满足条件就给容器注册bean,否则不注入
- 要作为自定义条件,需要创建自定义condition类,并要实现Condition接口,并实现match方法
- conditional不仅可以标在方法上,还可以标记在类上
//判断是否是Linux系统的条件
//要作为自定义条件,要实现Condition接口,并实现match方法
//AnnotatedTypeMetadata:注释信息
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//判断linux洗洗
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获得当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取到bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
String OSproperty = environment.getProperty("os.name");
if (OSproperty.contains("Mac OS X")){
return true;
}
return false;
}
}
另一个自定义条件
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
//获取操作系统信息
String OSproperty = environment.getProperty("os.name");
if (OSproperty.contains("Window")){
return true;
}
return false;
}
}
配置类信息
@Configuration
@ComponentScan(value = "com.atguigu")
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类信息
@Test
public void testBeans() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//获取ioc容器的运行环境
ConfigurableEnvironment environment=applicationContext.getEnvironment();
//获取操作系统名称
String property = environment.getProperty("os.name");
System.out.println(property);
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name:namesForType) {
System.out.println(name);
}
}
测试结果
Mac OS X
person
female
13、给IOC容器中注册组件的5种方法
- 包扫描+组件类上标注注解:(@Controller,@Service,@Repository,@Component)
- @Bean:导入第三方包的组件
- @Import:快速给容器导入一个组件
1)@Import(要导入到容器的组件),容器中就会自动注册这个逐渐,id默认是全类名
2)ImportSelector:返回需要导入的组件的全类名数组
4.使用ImportBeanDefinitionRegistrar
5.使用Spring提供的FactoryBean(工厂bean)注册组件
1)默认获得的是工厂bean调用getObject创建的对象
2)要获取工厂bean本身,需要给id前面加一个&标识
14、@Import 快速导入一个类
使用@Import快速为配置类导入一个bean类
可以同时导入多个bean类
需要再配置类上方书写
- 创建被导入的bean类
public class Color {
}
public class Red {
}
- 给配置类导入该类
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class})//在这里进行快速地导入,可以是数组形式
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类代码
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
person
female
15、ImportSelector接口导入一个类
- ImportSelector:返回需要导入的组件的全类名数组
- 需要实现ImportSelector接口并改写selectImports方法
创建需要被导入的类
public class Blue {
}
public class Yellow {
}
创建自己的Import类
public class MyImportSelect implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//返回值是要导入到容器中的组件全类名
//annotationMetadata:注解信息
return new String[]{"com.atguigu.bean.Blue", "com.atguigu.bean.Yellow"};
}
}
在配置类中设置@Import导入的自定义类选择器
注意:@Import({Color.class, Red.class,MyImportSelect.class})
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试代码
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
Color,Red,Blue,Yellow都有了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
16、使用ImportBeanDefinitionRegistrar接口导入类
自定义导入的类定义,需要实现ImportBeanDefinitionRegistrar接口,并重写 registerBeanDefinitions方法
创建一个需要被注入的类
public class RainBow {
}
创建自定义的注册类信息类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
//annotationMetadata:当前类的注解信息
//beanDefinitionRegistry:beanDefinition注册类
//把所有需要添加到容器中的bean,调用beanDefinitionRegistry.registerBeanDefinition手动注册类
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
boolean red = beanDefinitionRegistry.containsBeanDefinition("com.atguigu.bean.Red");//判断定义中是否有红色
boolean blue = beanDefinitionRegistry.containsBeanDefinition("com.atguigu.bean.Blue");//判断定义中是否有蓝色
if(red && blue){
//指定bean名
RootBeanDefinition rainbowDefinition = new RootBeanDefinition(RainBow.class);
//注册了一个bean,并指定了一个类名(别名)
beanDefinitionRegistry.registerBeanDefinition("rainbow", rainbowDefinition);
}
}
}
在配置类中进行配置
注意:@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
}
测试类
@Test
public void testImport(){
printBeans(applicationContext);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果
显示了rainbow
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
rainbow
17、使用FactoryBean接口导入类
创建自定义工厂类,实现FactoryBean接口,并改写一下方法
getObject() //返回工厂生产的类对象
getObjectType()//返回工厂生产的类类型
isSingleton() //返回单例
创建自定义工厂类
这里实现FactoryBean接口,实现三个方法,注意泛型中使用Color类
public class ColorFactory implements FactoryBean<Color> {
//返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
System.out.println("color factory generate a instance");
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
@Override
public boolean isSingleton() {
//true:返回单例,在容器中保存一份
//false:返回多份类实例,每次获取工厂bean都会创建一个新的对象
return false;
}
}
在配置类中定义这个类组件
注意:
@Bean
public ColorFactory colorFactoryBean(){
return new ColorFactory();
}
}
@Configuration
@ComponentScan(value = "com.atguigu")
@Import({Color.class, Red.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
// @Scope("prototype")
@Lazy
@Bean("person")//指定bean的自定义id
public Person person(){
return new Person("张三",20);
}
@Conditional({WindowsCondition.class})
@Bean("male")
public Person personMale(){
return new Person("lisi",33);
}
@Conditional({LinuxCondition.class})
@Bean("female")
public Person personFemale(){
return new Person("wanger",23);
}
@Bean
public ColorFactory colorFactoryBean(){
return new ColorFactory();
}
}
测试类文章来源:https://www.toymoban.com/news/detail-623245.html
public class MainTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void testImport(){
printBeans(applicationContext);
//工厂bean获取的是调用的是getObject创建的对象(Color类)
Object bean1 = applicationContext.getBean("colorFactoryBean");
Object bean2 = applicationContext.getBean("colorFactoryBean");
System.out.println(bean1);
System.out.println(bean2.getClass());//class com.atguigu.bean.Color
System.out.println(bean1==bean2);
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name:beanDefinitionNames) {
System.out.println(name);
}
}
测试结果文章来源地址https://www.toymoban.com/news/detail-623245.html
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookDAO
bookService
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
person
female
colorFactoryBean
rainbow
color factory generate a instance
color factory generate a instance
com.atguigu.bean.Color@79c97cb
class com.atguigu.bean.Color
false
到了这里,关于spring注解驱动开发(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!