1. 基本介绍
-
为了简化操作与开发,Spring从2.5版本开始支持注解可以从xml配置文件中脱离出来,直接写在Java代码中修改也变得方便。
-
Spring4版本之后,在使用注解时需要引入AOP的Maven依赖,以及context上下文的约束。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启组件扫描 扫描路径下的所有注解-->
<context:component-scan base-package="com.pojo"/>
<!-- 开启注解的支持-->
<context:annotation-config/>
</beans>
1. Component注解
-
之前所有的创建对象都是通过xml配置文件创建bean,注解中提供了4种创建bean的方式:Component、Service、Controller、Repository四种。
-
它们都是同样的作用,只不过后面三种是MVC架构中为了区分Service层、Controller层、dao层而细化的。并没有强制要求哪个层必须使用哪个!
-
并且它们直接在注解中设置value属性值,等价于bean 中的id;不指定value默认情况下value = 首字母小写的类名。
/*
@Component(value = "dog1") 等价于 <bean id="dog1" class="类的全路径"/>
不指定value默认情况下value = 首字母小写的类名(dog)
*/
@Component(value = "dog1")
public class Dog {
public void speak(){
System.out.println("wang~");
}
}
@Test
public void test1(){
// @Component、 @Service、 @Controller、 @Repository。
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Dog dog = context.getBean("dog1", Dog.class);
dog.speak();
}
当加载配置文件的时候,Spring通过配置文件(开启扫描),扫描该路径下的所有注解进行bean的创建;其他三个注解@Service(服务层)、@Controller(控制层)、@Repository(持久层)效果都一样。
2. Autowired注解
-
@Autowired注解:用于自动注入引用类型的属性,与xml配置文件中的byType自动注入效果一样,根据类型进行注入,因此可以猜到Autowired完成自动注入的前提是bean只有一个。
-
@Autowired注解可选参数required:required默认为true,表示这个属性是必要的,也可以置为false表示这个属性可以为空。
-
@Autowired注解的强大:xml配置bean的时候进行注入需要使用set或者构造器注入,使用Autowired可以没有set方法!
使用流程:
-
首先将所需要的bean对象进行创建,可以使用component注解也可以使用xml配置进行bean创建
-
使用Autowired进行注解的标记属性,确保属性是唯一的。因为Autowired是根据byType进行注入。
-
获取对象
@Repository(value = "userDao")
public class UserDaoImpl {
}
@Service(value = "userService")
public class UserService {
@Autowired(required = true) //该属性不能为空,默认就是true
private UserDaoImpl userDaoImpl;
public UserDaoImpl getUserDaoImpl() {
return userDaoImpl;
}
}
@Test
public void test2(){
// @Autowired、 @Required、 @Nullable、 @Qualifier
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService service = context.getBean("userService", UserService.class);
System.out.println(service.hashCode());
System.out.println(service.getUserDaoImpl().hashCode());
}
3. Qualifier注解
-
@Qualifer注解:无法单独使用需要结合Autowired完成;它是根据byName进行注入。
-
当Autowired注入时bean对象不止一个是可以使用Qualifier(value = “bean的id”)完成。
public interface UserDao {
public void add();
}
//第一种实现
@Repository(value = "userDao1")
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("第一种实现");
}
}
//第二种实现
@Repository(value = "userDao2")
public class UserDaoImpl2 implements UserDao {
@Override
public void add() {
System.out.println("第二种实现");
}
}
@Service(value = "userService")
public class UserService {
@Autowired()
@Qualifier(value = "userDao2") //byName区分哪一个bean
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
}
@Test
public void test2(){
// @Autowired、 @Required、 @Nullable、 @Qualifier
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService service = context.getBean("userService", UserService.class);
System.out.println(service.hashCode());
service.getUserDao().add();
}
4. Resource注解
-
Resource注解是Autowired注解 + Qualifier注解的结合体;
-
既可以根据类型注入,也可以根据名称注入!但是它不是Spring的注解,它是Java的注解!
-
根据类型注入:@Resource
-
根据名称注入:@Resource(name = “id”)
-
Resource装配bean是先根据byName进行装配,如果byName找不到在根据类型进行装配!
import javax.annotation.Resource;
@Service(value = "userService")
public class UserService {
// @Autowired
// @Qualifier(value = "userDao2")
@Resource(name = "userDao1")
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
}
@Test
public void test3(){
// @Resource 和 @Value
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService service = context.getBean("userService", UserService.class);
System.out.println(service.hashCode());
service.getUserDao().add();
}
5. Value注解
- Autowired、Qualifier、Resource注解都是针对引用类型的数据进行装配的,Value注解是针对基本数据类型进行装配包括String类型!
@Test
public void test3(){
// @Resource 和 @Value
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
person.speak();
}
6. Required注解、Nullable注解
-
Required注解:之前可以看到Autowired注解中可以设置required的值为true表名这个属性不能为空,同样@Required表明这个属性不能为空;不过在Spring5.1版本之后废弃了;可能是因为直接集成到了Autowried中。
-
Nullable注解:Autowired注解同样也可以设置required的值为false表名这个属性可以为空,Nullable也是同样的意思。
7. Scope注解
- 用于配置bean对象的实例的作用域的,与传统的xml中的scope一样,支持singleton、prototype、request、session…
//单例
@Scope(value = "singleton")
@Component(value = "dog1")
public class Dog {
public void speak(){
System.out.println("wang~");
}
}
//原型(多例)
@Scope(value = "prototype ")
@Component(value = "dog1")
public class Dog {
public void speak(){
System.out.println("wang~");
}
}
总结
xml 与 注解:
-
xml灵活度更高,适用任何场景 ,结构清晰维护方便
-
注解不是自己提供的类使用不了,开发简单方便
建议xml + 注解结合使用。