详细分析Java中的new以及@Autowired(附Demo)

前言

起因是Springboot项目在使用@Autowired注解后,需要使用到new的属性,但发现出现空指针,这表明注解失效

对于更多的Java知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. 差异

@Autowired 注解是 Spring 框架中用来自动装配 Bean 的注解

当一个类中使用 @Autowired 注解时,Spring 容器会在初始化这个类的时候自动装配相应的 Bean,而不需要手动去创建对象

而使用 new 关键字来构建对象是传统的 Java 对象创建方式,即通过手动调用构造函数来创建对象

这种方式不会触发 Spring 的自动装配机制,所以即使已经在 Spring 的配置文件中定义了相应的 Bean,也不会被注入,而且当通过 new 关键字创建对象时,这个对象中使用 @Autowired 注解的成员变量也不会被自动注入,因此它们会保持为 null。

所以,主要的区别在于:

  • @Autowired 注解是 Spring 提供的一种依赖注入的方式,通过它可以让 Spring 容器自动装配需要的 Bean,而不需要手动创建对象
  • 使用 new 关键字创建对象是传统的 Java 对象创建方式,不会触发 Spring 的自动装配机制,因此无法实现依赖注入

2. 场景

2.1 @Autowired

  • @Autowired 注解是 Spring 框架中的一个注解,用于自动装配 Bean
  • 当类中的某个属性使用 @Autowired 注解标注时,Spring 容器会自动在容器中寻找匹配类型的 Bean,并将其注入到该属性中
  • 自动装配可以通过 byType、byName、构造器等方式进行

实际Demo如下:

// UserService.java
public interface UserService {
    void createUser();
}

// UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
    public void createUser() {
        System.out.println("Creating a user...");
    }
}

// AdminServiceImpl.java
@Service
public class AdminServiceImpl implements UserService {
    public void createUser() {
        System.out.println("Creating an admin...");
    }
}

// UserController.java
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/createUser")
    public String createUser() {
        userService.createUser();
        return "User created successfully!";
    }
}

2.2 new

使用 new 关键字创建对象时,不会触发 Spring 的自动装配机制,因为这只是普通的 Java 对象创建方式

下面这种方式会造成null,注意差别

// User.java
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
    public void createUser() {
        System.out.println("Creating a user...");
    }
}

// UserController.java
public class UserController {
    @Autowired
    private UserService userService;

    public void createUserManually() {
        // 使用 new 关键字手动创建 User 对象
        User user = new User("John");
        // 此时 userService 为 null,无法自动注入
        userService.createUser();
    }
}

真正不会造成null的构建对象:

public class Car {
    private String brand;
    private String model;

    public Car(String brand, String model) {
        this.brand = brand;
        this.model = model;
    }

    public void drive() {
        System.out.println("Driving " + brand + " " + model);
    }
}

public class CarDealer {
    public void sellCar() {
        // 使用 new 关键字创建 Car 对象
        Car car = new Car("Toyota", "Corolla");
        // 执行 Car 对象的方法
        car.drive();
    }
}
  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,下面是一个基于 Spring Boot 的用户登录案例: 1. 创建 User 实体类 ```java @Data public class User { private String username; private String password; } ``` 2. 创建 UserService 接口和实现类 ```java public interface UserService { User login(String username, String password); } @Service public class UserServiceImpl implements UserService { @Override public User login(String username, String password) { // 在这里校验用户名和密码是否正确,省略实现 return new User(username, password); } } ``` 3. 创建 UserController 控制器 ```java @Controller public class UserController { @Autowired private UserService userService; @PostMapping("/login") @ResponseBody public String login(@RequestBody User user) { User loginUser = userService.login(user.getUsername(), user.getPassword()); if (loginUser != null) { return "登录成功"; } else { return "用户名或密码错误"; } } } ``` 4. 配置 mybatis 和数据库信息 在 application.properties 文件添加以下配置: ``` spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10 spring.datasource.username=root spring.datasource.password=root mybatis.mapper-locations=classpath:mapper/*.xml ``` 5. 创建 UserMapper 接口和 XML 映射文件 ```java @Mapper public interface UserMapper { User selectByUsernameAndPassword(@Param("username") String username, @Param("password") String password); } ``` 在 mapper 文件夹下创建 UserMapper.xml 文件,编写 SQL 语句: ```xml <mapper namespace="com.example.demo.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.example.demo.entity.User"> <id column="username" property="username" /> <result column="password" property="password" /> </resultMap> <select id="selectByUsernameAndPassword" resultMap="BaseResultMap"> select * from user where username=#{username} and password=#{password} </select> </mapper> ``` 6. 编写测试代码 ```java @RunWith(SpringRunner.class) @SpringBootTest public class UserControllerTests { @Autowired private UserController userController; @Test public void testLogin() { User user = new User(); user.setUsername("admin"); user.setPassword("123456"); String result = userController.login(user); assertEquals("登录成功", result); } } ``` 以上就是一个基于 Spring Boot 的用户登录案例的实现过程,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值