Bean对象更简单的读取和存储

在这里插入图片描述

hi,大家好,今天为大家继续带来Spring相关知识
上一期我们已经学习了Spring对象的基本的存储和读取了,但是那个过程比较复杂,我们来学习Bean更加简单的存储和读取👀

🧊1.存储Bean对象

我们上一期学习的时候存储bean需要配置xml.现在我们需要一个注解就可以完成,但是要先配置路径

🍉1.1前置工作:配置扫描路径

在xml文件中配置扫描包路径,其实说的通俗一点就是Bean对象在哪个包,就写哪个路径
在这里插入图片描述
蓝色的这一块,作用是配置bean的扫描根路径,只有这个当前目录下的类才会扫描是否添加了注解,如果添加了注解,就将这个添加了注解的类放到IOC容器
红色的就是我创建的包,这个包名称要和spring-config里面的base-package里面引用的内容一样

🍉1.2 存储Bean对象(采用五大注解)

存储bean对象有两种方法
1.通过类注解(五大类)
2.通过方法注解

🌻1.2.1@Controller(控制器存储)

@Controller,控制器存储,作用是校验参数的合法性

package com.java.demo;

import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-21
 * Time: 15:09
 */
@Controller(value = "userinfo")
public class User {
        public void sayHi(){
            System.out.println("hi User");
        }
}

@Controller这里可以起一个名字,加上这个注解,就代表这个类已经被注入到了IOC容器中,我们来获取bean

import com.java.demo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-21
 * Time: 15:08
 */
public class APP {
    public static void main(String[] args) {
        //得到容器对象
        ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean对象
                User user=context.getBean("userinfo",User.class);
                //使用bean
        user.sayHi();

    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
也可以不设置,那么写的时候就是默认写成类名首字母小写
我们再次在com.java.demo包下创建一个Student类,不加注解,运行会报错,那么我们可以采用加注解,也可以采用xml的形式,这俩可以混用
在这里插入图片描述
在这里插入图片描述

import com.java.demo.Student;
import com.java.demo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-21
 * Time: 15:08
 */
public class APP {
    public static void main(String[] args) {
        //得到容器对象
        ApplicationContext context1=new
                ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean对象
                User user=context1.getBean("user",User.class);
                //使用bean
        user.sayHi();
        ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean对象
        Student student=context.getBean("student",Student.class);
        //使用bean
        student.sayHi();
    }
}

在这里插入图片描述
这下两个类都可以执行了
接下来我们不改变扫描路径,我们来验证一下该包的子包是否能执行,我们把这个例子放到@Service下面

1.2.2@Service(服务存储)

@Service属于服务层,主要功能是业务组装,负责调用其他接口

public class APP {
    public static void main(String[] args) {
        //得到容器对象
        ApplicationContext context1=new
                ClassPathXmlApplicationContext("spring-config.xml");
                UserService userService=context1.getBean("userService",UserService.class);
        userService.sayHi();
    }
}

在这里插入图片描述
说明子类也可以

为什么一定要设置扫描根路径呢?
是为了性能考虑,也可以不设置,让spring扫描Java包下所有的类,但是那样太低效了,规定一个范围,spring就会根据这个范围扫描它的类以及子包,提高了效率

🌻1.2.3@Repository(仓库存储)

@Resopority是仓库层,也称数据持久层,功能是实际业务处理

@Repository
public class UserService {
    public void sayHi(){
        System.out.println("hi, UserService");
    }
}

在这里插入图片描述
也可以得到结果

🌻1.2.4@Configuration(配置存储)

@Configuration
public class UserService {
    public void sayHi(){
        System.out.println("hi, UserService");
    }
}

在这里插入图片描述

🌻1.2.5@Component(组件存储,工具类)

@Component
public class UserService {
    public void sayHi(){
        System.out.println("hi, UserService");
    }
}

在这里插入图片描述

🍉1.3类注解

通过上述代码我们可以发现,这几个注解功能是⼀样的,为什么需要这么多的类注解呢,就像看到身份证号前几位就可以区分这个人是哪里人是一样的,在程序中,当程序员看到这些注解,就清楚的知道这个类的功能

🌻1.3.1类注解的作用

通过上述代码我们可以发现,这几个注解功能是⼀样的,为什么需要这么多的类注解呢,就像看到身份证号前几位就可以区分这个人是哪里人是一样的,在程序中,当程序员看到这些注解,就清楚的知道这个类的功能

🌻1.3.2类注解之间的关系

我们采用一个通俗的例子来进行讲解

比如小魏去坐高铁,那么首先要过安检,那么如果安检都过不去,那么就更不用提后面的事情了,此时的安检系统就相当于@Controller,过了安检以后,如果有问题可以去咨询台问,这个咨询台的工作人员是为大家服务的,那么这个相当于@Service,然后当听到工作人员说去某个窗口买票,然后小魏去到该窗口办理,这个窗口相当于@Repository,而这个等候厅的椅子啊这些都是组件,工具,这就相当于@Component.
配置层就是给该项目做一些配置的,比如设置端口号,session存储时间啥的,也就是@Configuration

项目里面的这几个关系是这样的
Java项目分层
在这里插入图片描述
在这里插入图片描述
看到@Controller是基于@Component实现的
在这里插入图片描述
@Service也是基于@Component实现的
在这里插入图片描述
@Repository基于@Componnent实现的
在这里插入图片描述
@Configuration基于@Component实现

这四个注解都基于@Component注解实现

🍉1.4 Bean的默认命名规则

🌻大驼峰命名

如果这个类的名称第一个字母大写,第二个字母小写,那么就用类名的小写形式,就像这样
在这里插入图片描述

🌻特殊案例

在这里插入图片描述

@Configuration
public class LApple {
    public void sayHi(){
        System.out.println("hi ,LApple");
    }
}
public class APP {
    public static void main(String[] args) {
        //得到容器对象
        ApplicationContext context1=new
                ClassPathXmlApplicationContext("spring-config.xml");
                 LApple  lApple=context1.getBean("lApple",LApple.class);
                 lApple.sayHi();
                 }
               }

在这里插入图片描述
可以看到报错了,说该类不存在

🌻解决办法

当遇到第一个字母是大写,第二个字母也是大写的时候我们怎么办呢?
返回它本来的类名即可
在这里插入图片描述
在这里插入图片描述
那么为什么会出现这样的问题呢?
咱们这个时候就需要看看Spring的源码了
在这里插入图片描述

    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        if (definition instanceof AnnotatedBeanDefinition) {
            String beanName = this.determineBeanNameFromAnnotation((AnnotatedBeanDefinition)definition);
            if (StringUtils.hasText(beanName)) {
                return beanName;
            }
        }

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
看到这里,会发现当名字为空或者长度为0时,返回本身,长度大于1或者第一个字母和第二个字母时大写字母时.返回本身,当第一个为大写,第二个不为大写,将第一个字母变为小写返回

🍉1.5 方法注解@Bean

🌻1.5.1方法注解配合类注解使用

创建一个Article

package com.java.demo.model;

public class Article {
    private int id;
    private String title;
    private   String content;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

再创建一个Articles类

package com.java.demo;

import com.java.demo.model.Article;
import org.springframework.context.annotation.Bean;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-21
 * Time: 19:26
 */
public class Articles {

    //要把当前返回的对象存储到IOC容器中
    @Bean
    public Article article(){
        //伪代码
        Article article=new Article();
        article.setId(1);
        article.setTitle("钢铁是怎样炼成的");
        article.setContent("一个人的一生不应该这样度过,不应该因碌碌无为而......");
        return article;
    }
}

在这里插入图片描述
啊哦,竟然报错了,因为@Bean注解必须结合五大注解一起使用
在这里插入图片描述
在这里插入图片描述
那么为什么一定要加这个注解呢,如果不加,那么spring的扫描工作量就会很大,要扫描com.java.demo下所有的方法看哪一个加了bean,效率很低,为了提高性能,就要加上
那么还有一个拓展性的问题,这个Articles会被注入吗?
我们来验证一下
在Articles创建一个sayHi方法

package com.java.demo;

import com.java.demo.model.Article;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-21
 * Time: 19:26
 */

@Component
public class Articles {

    //要把当前返回的对象存储到IOC容器中
    @Bean
    public Article article(){
        //伪代码
        Article article=new Article();
        article.setId(1);
        article.setTitle("钢铁是怎样炼成的");
        article.setContent("一个人的一生不应该这样度过,不应该因碌碌无为而......");
        return article;
    }
    public void sayHi(){
        System.out.println("hi Articles");
    }
}

import com.java.demo.Articles;

import com.java.demo.model.Article;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;


public class APP {
    public static void main(String[] args) {
       /* //得到容器对象
        ApplicationContext context1=new
                ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean对象*/
                //User user=context1.getBean("user",User.class);
                //使用bean
        //user.sayHi();
       ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean对象
        /*Student student=context.getBean("student",Student.class);*/
        //使用bean
        //

        Article article=context.getBean("article",Article.class);
        System.out.println(article.toString());
        Articles articles=context.getBean("articles",Articles.class);
        articles.sayHi();
    }
}

在这里插入图片描述

由结果看出Articles也是被注入的.即本身的类也会存到Spring中

🌻1.5.2@Bean获取时的注意事项

1.默认情况下,@Bean的默认名=方法名
比如在这里插入图片描述
这里的方法名就是类名的小写形式,那么就使用方法名就行
2如果是方法名写成别的名字
在这里插入图片描述
在这里插入图片描述

那么就会报错,这个时候就要给@Bean命名了

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
运行成功了

2.在这里插入图片描述

在这里插入图片描述
3.在这里插入图片描述

在这里插入图片描述
1.

2.
在这里插入图片描述
3.
在这里插入图片描述

以上是Bean的重命名三种方式

Bean支持多个名称命名
在这里插入图片描述
有一个问题,当这个bean设置了名称,还能用方法名获取吗?

在这里插入图片描述

答案是不能!!!
注意:当@Bean重命名之后,那么默认的使用方法名获取Bean对象的方式将失效!!!

有可能:Spring存储Bean的逻辑结构是多个名称对应同一个Bean对象

当有多个方法,bean的名称一样时,会发生什么呢?👀👀👀

@Order(20)
@Component
public class Articles {

    //要把当前返回的对象存储到IOC容器中
    @Bean(value="aaa")
    public Article article(){
        //伪代码
        Article article=new Article();
        article.setId(2);
        article.setTitle("钢铁是怎样炼成的");
        article.setContent("一个人的一生不应该这样度过,不应该因碌碌无为而......");
        return article;
    }
    @Bean("aaa")
    public Article article2(){
        //伪代码
        Article article=new Article();
        article.setId(1);
        article.setTitle("钢铁是怎样炼成的");
        article.setContent("一个人的一生不应该这样度过,不应该因碌碌无为而......");
        return article;
    }
    public void sayHi(){
        System.out.println("hi Articles");
    }
}

@Order(1)
@Controller()
public class User {
        public void sayHi(){
            System.out.println("hi User");
        }
    @Bean(value="aaa")
    public Article article3(){
        //伪代码
        Article article=new Article();
        article.setId(4);
        article.setTitle("钢铁是怎样炼成的");
        article.setContent("一个人的一生不应该这样度过,不应该因碌碌无为而......");
        return article;
    }
}

@Order代表的是执行的优先级,数字越大,优先级越高,越先执行
在这里插入图片描述
如果不加这个@Order,那么就按照代码执行顺序执行
如果多个Bean使用相同的名称,那么程序执行不会报错,但是第一个Bean对象之后的对象不会存放到容器中,后面再有相同名称的Bean存储的时候,容器会自动忽略,不会进行存储

🧊2.获取Bean对象(对象注入/对象装配)

获取Bean对象也叫做对象装配,就是把容器里的对象取出来放到某个类里面,有时候也叫对象注入

🍉2.1 属性注入

属性注入是使用@Autowired实现的
为了讲解这个例子,我们先创建一个标准的工程
在这里插入图片描述
在UserRepository中写一个方法,在UserService调用

package com.java.demo.dao;

import org.springframework.stereotype.Repository;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 8:43
 */
@Repository
public class UserRepository {
        public int add(){
            System.out.println("执行UserRepository 方法");
            return 1;
        }
}

package com.java.demo.service;

import com.java.demo.dao.UserRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 8:42
 */
@Service
public class UserService {
    public int add(){
        //传统写法
        /*UserRepository userRepository=new UserRepository();
        return userRepository.add();*/
        //Spring写法
        //依赖查找
       /* ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        UserRepository userRepository=context.getBean("userRepository",UserRepository.class);
        return userRepository.add();*/
        return 0;
    }
}

这两种写法都是很麻烦的,我们采取属性注入来解决

@Service
public class UserService {
    //属性注入
    @Autowired
    private UserRepository userRepository;//这里是依赖注入,从Spring当种找到UserRepository赋值给新的变量
    public int add(){
           return userRepository.add();
    }
}

我们现在验证一下UserService是否能拿到这个类.,我们采用单元测试的方法
快捷键alt+insert点击Test,点击生成方法,并且引入Junit依赖

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.3</version>
    <scope>test</scope>
</dependency>

创建单元测试代码

package com.java.demo.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import static org.junit.jupiter.api.Assertions.*;



class UserServiceTest {

    @org.junit.jupiter.api.Test
    void add() {
        ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        UserService userService=context.getBean("userService",UserService.class);
        userService.add();
    }
}

执行结果如下
在这里插入图片描述

在这里插入图片描述
这里的名字随便起,都可以执行
和之前的依赖查找不同,依赖查找依赖Bean名称进行查找

2.1.1当同一类型的多个bean被注入

@Authowired
依赖注入流程:首先看类型,根据类型从容器中获取对象,如果该类型只有一个,而且只有一个,那么直接获取注入到当前对象,如果该类型有多个对象,那就根据名称进行匹配
我们来使用代码来看一下

package com.java.demo.model;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 9:24
 */
public class Student {
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

package com.java.demo.model;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 9:25
 */
@Component
public class Students {
    @Bean("student1")
   public Student student1(){
       Student student1=new Student();
       student1.setName("zhangsan");
       return student1;
   }
   @Bean("student2")
    public Student student2(){
        Student student2=new Student();
        student2.setName("wangwu");
        return student2;
   }
}

package com.java.demo.service;

import com.java.demo.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 9:31
 */
@Service
public class UserService2 {
    //属性注入获取
    @Autowired
    private Student student;

    public void sayHi(){
        System.out.println(student.toString());
    }
}

再做一次单元测试

package com.java.demo.service;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 9:34
 */
class UserService2Test {

    @Test
    void sayHi() {
        ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        UserService2 userService2=context.getBean("userService",UserService2.class);
        userService2.sayHi();
    }
}

🌻2.1.2出现的问题

在这里插入图片描述

因为在Service调用的时候,命名的时候采用的是student,而我们在创建的时候命名的是student1,student2,没有student,所以报错,同类型的Bean存储到容器多个,获取时报错,怎样解决?

🌻2.1.3解决办法

1.将属性的名字和Bean的名字对应上
在这里插入图片描述
在这里插入图片描述
2.采用@Qualifier注解来解决,这个注解是筛选的意思,我就可以不改属性名.
在这里插入图片描述
在这里插入图片描述

3.使用@Resource注解
在这里插入图片描述
@Resource里面可以设置bean的名称
在这里插入图片描述

🍉2.2 Setter注入

@Service
public class UserService3 {
    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public void sayHi(){
        System.out.println("执行了UserService3方法");
        userRepository.add();
    }
}

在这里插入图片描述
生成单元测试
在这里插入图片描述
必须结合@Authowired使用

🍉2.3 构造方法注入

首先了解这个方式是Spring官方推荐的方式,是在Spring(4.x)之后被推荐的,这个版本之前推荐的是setter注入
在这里插入图片描述
这里有一个小的知识点,为什么这三种注入都需要创建这个类变量,因为创建类变量.这个类的所有方法都可以调用这个变量
标准写法

@Service
public class UserService4 {

    private UserRepository userRepository;
    @Autowired
        public UserService4(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public void sayHi(){
        System.out.println("执行UserService方法");
        userRepository.add();
    }
}

生成单元测试代码看结果
在这里插入图片描述
不加@Autowired,也可以执行,但是只可以在当前类只有一个构造方法的时候才能用
在这里插入图片描述
多个构造方法时不可以省略,因为要判断注入哪一个构造方法

🍉2.4三种注入的优缺点

1.属性注入
优点:使用简单

缺点:无法注入final修饰的变量
在这里插入图片描述
要想不报错,要么赋值,要么就在构造方法赋值

2.通用性问题:只能适用于IOC容器

3.设计问题:更容易违背单一设计原则

2.Setter注入

优点:通常Setter只set一个属性,所以Setter注入更符合单一设计原则

缺点:
1.无法注入一个final修饰的变量
在这里插入图片描述
2.setter注入的对象容易被多次调用和被修改.setter本来就是一个方法,因为是一个方法,就有可能被多次调用和修改

3.构造方法注入

优点

1.可以注入final修饰的变量了

2.注入的对象不会被修改,因为构造方法只加载一次,因为它随着JVM的启动而加载

3.保证注入的对象是被完全初始化的

4.通用性更好

缺点:
写法复杂

无法解决循环依赖的问题

🍉2.5@Resource(另一种注入)

进行类注入时,除了使用@Autowired以外,还能使用@Resource
在这里插入图片描述
在这里插入图片描述

2.6@Autowired@Resource的区别🐶

1.出身不同:@Resource来自于JDK,@Autowired来自Spring框架
2.参数支持不同:@Resource支持很多参数设置,@Autowired只有一个参数设置,可以看源码
3.使用上:@Resource不支持构造方法注入,@Autowired支持
4.idea兼容性不同:@Autowired在idea专业版本下可能会报错,@Resource不会

😎3.综合练习

在 Spring 项⽬中,通过 main ⽅法获取到 Controller 类,调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤Service 类,Service 再通过注⼊的⽅式获取到 Repository 类,Repository 类⾥⾯有⼀个⽅法构建⼀个 User 对象,返回给 main ⽅法。Repository ⽆需连接数据库,使⽤伪代码即可
在这里插入图片描述

package com.java.demo.model;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 13:22
 */
public class User {
    private int id;
    private  String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

package com.java.demo.repository;

import com.java.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Repository;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 13:21
 */
@Repository
public class UserRepository {
    @Bean
    public User getUser(){
        User user=new User();
        user.setId(1);
        user.setName("zhangsan");
        return user;
    }
}

package com.java.demo.service;

import com.java.demo.model.User;
import com.java.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 13:28
 */
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public User getUser(){
        return userRepository.getUser();
    }

}

package com.java.demo.controller;

import com.java.demo.model.User;
import com.java.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 13:36
 */
@Controller
public class UserController {
    @Autowired
    private UserService userService;
    public User getUser(){
        return userService.getUser();
    }
}

package com.java.demo;

import com.java.demo.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-07-22
 * Time: 13:17
 */
public class APP {
    public static void main(String[] args) {
        //这个静态方法是在Spring执行之前,所以拿不到注入对象,此时我们采取普通形式
        ApplicationContext context=new
                ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController=context.getBean("userController",UserController.class);
        System.out.println(userController.getUser());
    }
}

今天的讲解就到这里,我们下期再见,886~~~
在这里插入图片描述

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值