2023.11.11
注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。
负责声明Bean的注解,常见的包括四个:
- @Component
- @Controller
- @Service
- @Repository
通过源码可以发现,@Controller、@Service、@Repository这三个注解都是@Component注解的别名。也就是说:这四个注解的功能都一样。用哪个都可以。
只是为了增强程序的可读性,建议:
- 控制器类上使用:Controller
- service类上使用:Service
- dao类上使用:Repository
他们都是只有一个value属性。value属性用来指定bean的id,也就是bean的名字。
Spring注解的简单使用
配好相关环境之后,在Bean类上使用注解:
package spring;import org.springframework.stereotype.Component;@Component(value = "userBean")
public class User {
}
编写测试程序:
package test;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.User;public class IocAnnotationTest {@Testpublic void testBeanComponent(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println(userBean);}
}
运行结果:
ps:如果注解的属性名是value,那么value是可以省略的。
ps:如果把value属性彻底去掉,spring会被Bean自动取名,并且默认名字是:Bean类名首字母小写。
负责注入的注解
@Component @Controller @Service @Repository 这四个注解是用来声明Bean的,声明后这些Bean将被实例化。接下来看看如何给Bean的属性赋值。给Bean属性赋值需要用到这些注解:
- @Value
- @Autowired
- @Qualifier
- @Resource
@Value:
当属性的类型是简单类型时,可以使用@Value注解进行注入。
使用@Value注解修改bean代码:
package spring;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component(value = "userBean")
public class User {@Value("jay")private String name;@Value("23")private int age;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
运行测试程序,结果如下:
通过以上代码可以发现,我们并没有给属性提供setter方法,但仍然可以完成属性赋值。如果提供setter方法,并且在setter方法上添加@Value注解,也可以完成注入,这里就不测试了。为了简化代码,以后我们一般不提供setter方法,直接在属性上使用@Value注解完成属性赋值。
@Autowired与@Qualifier:
@Autowired注解可以用来注入非简单类型。单独使用@Autowired注解,默认根据类型装配。(默认是byType)。
通过源码得知,该注解可以标注在:构造方法上、方法上、形参上、属性上、注解上。
该注解还有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错。
@Autowired注解默认根据类型注入。如果要根据名称注入的话,需要配合@Qualifier注解一起使用。
@Resource
@Resource注解也可以完成非简单类型注入,它和@Autowired注解有什么区别?
- @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
- @Autowired注解是Spring框架自己的。
- @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。
- @Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。
- @Resource注解用在属性上、setter方法上。
- @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。
下面使用代码简单使用一下这个注解:
编写接口:
package dao;public interface UserDao {void insert();
}
实现该接口的类:
package dao.impl;import dao.UserDao;
import org.springframework.stereotype.Repository;@Repository("userDaoImplForMysql")
public class UserDaoImplForMysql implements UserDao {@Overridepublic void insert() {System.out.println("Mysql数据库正在插入数据");}
}
service类:
package service;import dao.UserDao;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;@Service("userService") //纳入容器管理
public class UserService {@Resource(name = "userDaoImplForMysql")private UserDao userDao;public void save(){userDao.insert();}
}
测试程序:
@Testpublic void testResource(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");UserService userService = applicationContext.getBean("userService", UserService.class);userService.save();}
运行结果: