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

相关文章
|
5月前
|
人工智能 Java 数据库
飞算 JavaAI:革新电商订单系统 Spring Boot 微服务开发
在电商订单系统开发中,传统方式耗时约30天,需应对复杂代码、调试与测试。飞算JavaAI作为一款AI代码生成工具,专注于简化Spring Boot微服务开发。它能根据业务需求自动生成RESTful API、数据库交互及事务管理代码,将开发时间缩短至1小时,效率提升80%。通过减少样板代码编写,提供规范且准确的代码,飞算JavaAI显著降低了开发成本,为软件开发带来革新动力。
|
5月前
|
前端开发 Java UED
从基础到进阶:Spring Boot + Thymeleaf 整合开发中的常见坑与界面优化
本文深入探讨了 **Spring Boot + Thymeleaf** 开发中常见的参数绑定问题与界面优化技巧。从基础的 Spring MVC 请求参数绑定机制出发,分析了 `MissingServletRequestParameterException` 的成因及解决方法,例如确保前后端参数名、类型一致,正确设置请求方式(GET/POST)。同时,通过实际案例展示了如何优化支付页面的视觉效果,借助简单的 CSS 样式提升用户体验。最后,提供了官方文档等学习资源,帮助开发者更高效地掌握相关技能。无论是初学者还是进阶用户,都能从中受益,轻松应对项目开发中的挑战。
175 0
|
3月前
|
Java 测试技术 数据库
说一说 SpringBoot 整合 Junit5 常用注解
我是小假 期待与你的下一次相遇 ~
|
3月前
|
Java API 微服务
Java 21 与 Spring Boot 3.2 微服务开发从入门到精通实操指南
《Java 21与Spring Boot 3.2微服务开发实践》摘要: 本文基于Java 21和Spring Boot 3.2最新特性,通过完整代码示例展示了微服务开发全流程。主要内容包括:1) 使用Spring Initializr初始化项目,集成Web、JPA、H2等组件;2) 配置虚拟线程支持高并发;3) 采用记录类优化DTO设计;4) 实现JPA Repository与Stream API数据访问;5) 服务层整合虚拟线程异步处理和结构化并发;6) 构建RESTful API并使用Springdoc生成文档。文中特别演示了虚拟线程配置(@Async)和StructuredTaskSco
311 0
|
5月前
|
人工智能 Java 定位技术
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
本文详细讲解了Java开发者如何基于Spring AI Alibaba框架玩转MCP(Model Context Protocol),涵盖基础概念、快速体验、服务发布与调用等内容。重点包括将Spring应用发布为MCP Server(支持stdio与SSE模式)、开发MCP Client调用服务,以及在Spring AI Alibaba的OpenManus中使用MCP增强工具能力。通过实际示例,如天气查询与百度地图路线规划,展示了MCP在AI应用中的强大作用。最后总结了MCP对AI开发的意义及其在Spring AI中的实现价值。
1376 9
|
5月前
|
人工智能 缓存 自然语言处理
保姆级Spring AI 注解式开发教程,你肯定想不到还能这么玩!
这是一份详尽的 Spring AI 注解式开发教程,涵盖从环境配置到高级功能的全流程。Spring AI 是 Spring 框架中的一个模块,支持 NLP、CV 等 AI 任务。通过注解(如自定义 `@AiPrompt`)与 AOP 切面技术,简化了 AI 服务集成,实现业务逻辑与 AI 基础设施解耦。教程包含创建项目、配置文件、流式响应处理、缓存优化及多任务并行执行等内容,助你快速构建高效、可维护的 AI 应用。
|
2月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
665 0
|
6月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
263 0