Spring注解开发详细教程(一)

简介: Spring注解开发详细教程

Spring注解开发详细教程 (配合雷神的视频)

一、AnnotationConfigApplicationContext

1.配置类

1.1使用传统xml方式

applicationContext.xml:

<bean id="person" class="com.rg.domain.Person" >
    <property name="name" value="张三"/>
    <property name="age" value="19"/>
</bean>

person类:

package com.rg.domain;
public class Person {
    private String name;
    private Integer age;
    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 Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类:

@Test
public void test01(){
    //加载配置文件
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    Person person = (Person) applicationContext.getBean("person");//通过id获取实体
    System.out.println(person);
}

1.2使用配置类方式:

MainConfig 配置类

//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
public class MainConfig {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person") //修改方法名称
    public Person person(){
        return new Person("lisi",20);
    }
}

测试类

@Test
public void test02(){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    Person person = applicationContext.getBean(Person.class);//通过类名来获取
    System.out.println(person);
}

2.包扫描

2.1传统xml方式:

<!--包扫描,只要标注了@Controller,@service,@Repository,@Component 类对象就会被自动加载到IOC容器中-->
<context:component-scan base-package="com.rg"/>

2.2注解方式:

MainConfig配置类

//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
@ComponentScan("com.rg")
public class MainConfig {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person") //修改方法名称
    public Person person(){
        return new Person("lisi",20);
    }
}

项目结构:

9c3e8794addd47e88aabf736f7095196.png

其中controller,dao,service中的类均使用相对应的注解.

测试类:

@Test
public void test03(){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    String[] names = applicationContext.getBeanDefinitionNames();//获取容器中所有的对象名称
    for (String name : names) {
        System.out.println(name);
    }
}

运行结果:

b4acae03e9484fad87b0b2bbe2e314c1.png

二、组件添加

1.@ComponentScan

1.1传统xml

<!--包扫描,只要标注了@Controller,@service,@Repository,@Component 类对象就会被自动加载到IOC容器中-->
<context:component-scan base-package="com.rg" use-default-filters="false">
     <!--use-default-filters : 是否使用默认的过滤器,默认值true 扫描包中的全部文件-->
   <!-- 注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖 -->
    type可为regex (正则),annotation(注解),assignable(接口或类)
   <context:exclude-filter type="assignable" expression="com.rg.controller.BookController"/>
        <context:include-filter type="assignable" expression="com.rg.service.BookService"/>
</context:component-scan>

1.2使用配置类

1.2.1ComponentScan注解的基本使用
//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
//JDK8之后可以写多个ComponentScan;如果不是该版本则可 使用ComponentScans属性
//注意
@ComponentScan(value="com.rg",includeFilters = {
        @ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class})},
        useDefaultFilters = false)
@ComponentScans(
        value = {
                @ComponentScan(value="com.rg",includeFilters = {
                        @ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class}),//第一个过滤器,根据注解类型
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}),//根据给定的类型
                },
                 useDefaultFilters = false),
                @ComponentScan(),
                //...
        }
)
//@ComponentScan  value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
public class MainConfig {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person") //修改方法名称
    public Person person(){
        return new Person("lisi",20);
    }
}

测试结果(测试类和上一个相同):

只有Controller包和service包中创建的对象

4f57eb6533fb44d29d45fe0b16d6404a.png

注意: pom.xml中的

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>


控制的是编译使用的JDK版本,如果此处使用的是JDK7,则MainConfig上无法添加多个@ComponentScan.

1.2.2自定义过滤器

在config包中创建MyTypeFilter类,并继承TypeFilter接口,写过滤条件.


public class MyTypeFilter implements TypeFilter {
    /**
     *
     * @param metadataReader:读取到的当前正在扫描的类的信息
     * @param metadataReaderFactory:可以获取到其他任何类的信息
     * @return
     * @throws IOException
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前扫描的类信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        String className = classMetadata.getClassName();//获取当前的类名
        System.out.println("-->" + className);
        if (className.contains("er")) {//如果类名包含er
            return true;//被过滤器过滤
        }
        return false;//不被过滤
    }
}

MainConfig中引入:

@ComponentScan(value="com.rg",includeFilters = {
        // @ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
        // @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}),
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
        }, useDefaultFilters = false)
@Configuration //告诉Spring这是一个配置类
public class MainConfig {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person") //修改方法名称
    public Person person(){
        return new Person("lisi",20);
    }
}

测试结果:

第一部分是符合条件的类名称,第二部分是存入到IOC容器中的对象的名称.

5ab32be30d044348b62f328a89eec194.png

2.@Scope

MainConfig:

//默认是单实例的
/**
 * * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
 * * @see ConfigurableBeanFactory#SCOPE_SINGLETON
 * * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
 * * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION session
 * @return\
 * @Scope:调整作用域
 * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
 *                 每次获取的时候才会调用方法创建对象;
 * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
 *           以后每次获取就是直接从容器(map.get())中拿,
 * request:同一次请求创建一个实例
 * session:同一个session创建一个实例
 *
 * 懒加载:
 *        单实例bean:默认在容器启动的时候创建对象;
 *        懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
 *
 */
@Scope( )
@Configuration
public class MainConfig2 {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person(){
        System.out.println("给容器中添加Person...");
        return new Person("lisi",20);
    }
}

测试:

@Test
public void test04(){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
    //System.out.println("IOC容器创建完成...");
    //System.out.println("hahha嗷嗷嗷");
    //   Person person = (Person) applicationContext.getBean("person");
    //  Person person2 = (Person) applicationContext.getBean("person");
    //  System.out.println(person == person2); //当为默认时,结果为true,当为prototype结果为false.
}

运行结果:

e4587a099463419dace0e72f3cd73389.png

当修改为@Scope(“propotype”)时,会先创建IOC容器,然后每次获取才调方法,创对象.

12fe35246d3e43acae21553858668a3b.png

:此处会出现@Scope(“propotype”)失效的问题,解决办法还没有找到…


3.@Lazy

单实例bean:默认在容器启动的时候创建对象;

懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化.

MainConfig

@Lazy
@Scope
@Configuration
public class MainConfig2 {
    //给容器注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person")
    public Person person(){
        System.out.println("给容器中添加Person...");
        return new Person("lisi",20);
    }
}

测试:

@Test
public void test04(){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
    System.out.println("IOC容器创建完成...");
    //System.out.println("hahha嗷嗷嗷");
       Person person = (Person) applicationContext.getBean("person");
     Person person2 = (Person) applicationContext.getBean("person");
     System.out.println(person == person2);
}

测试结果:

da8d9e25ca81486d899b07338989f4b0.png

相关文章
|
13天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
34 0
|
1月前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
20天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
43 4
SpringBoot必须掌握的常用注解!
|
11天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
22 2
|
22天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
75 2
|
22天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
34 1
|
29天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
68 2
|
1月前
|
XML Java 数据格式
提升效率!Spring Boot 开发中的常见失误轻松规避
本文深入探讨了在 Spring Boot 开发中常见的失误,包括不当使用注解、不良异常处理、低效日志记录等,提供了有效的规避策略,帮助开发者提升代码质量和系统性能,构建更健壮、高效的应用程序。
|
16天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
30 0
|
17天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
12 0
下一篇
无影云桌面