Spring 注解方式

准备工作

  从 Spring 2.5 开始就可以使用注解来配置依赖注入,只需要在相关类、方法、属性上声明注解即可。
  需要注意的是,默认情况下,Spring 容器中注解是不生效的,因此在配置使用注解之前需要在 Spring 配置文件中启用它。

  配置注解生效的步骤:
  1. 在根标签 <beans> 中加上 context 命名空间,并为其设置 schemaLocation

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlsn:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context.xsd">
</beans>

  2. 在根标签 <beans> 内,加上<context:annotation-config />

<beans>
	<!-- 启用注解配置 -->
	<context:annotation-config />
</beans>

注解配置

@Required 注解

  Required —— 必需的。
  可以使用位置: 在所对应的属性的 set 方法上。
  作用: 通过 Spring 形式对这个类实例化时,必须对这个属性进行 set,也就是说必须给这个属性赋值。

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

  如果将在某个属性的 set 方法上加了 @Required 注解,但是在实例其对象时,没有对该属性赋值,会抛出 Bean 实例化失败的异常:org.springframework.beans.factory.BeanInitializationException

@Autowired 注解

  @Autowired 注解对应我们在 Spring XML 配置中 bean 标签的 autowire 属性。
  PS:属性没有 d,注解有 d。

  默认情况下,@Autowired 注入首先根据 byType 注入,如果 byType 查找到的 bean 是多个时,根据 byName 注入。

  可以使用位置: set 方法上、放在属性上(此时可以省略 set 方法)、构造方法上

// 放在 set 方法上
@Autowired
public void setD1(Demo1 obj1) {
    
    
	this.d1 = obj1;
}
// 放在属性上,此时可省略 set 方法
@Autowired
private Demo1 d1;
// 放在构造方法上
@Autowired
public Demo3(Demo1 d1){
    
    
	this.d1 = d1;
}

  1. 默认情况下,@Autowired 注解 是必须要进行自动装配的,也就是要求 Spring 容器中至少有一个 Demo1 类型的 bean,否则报错

@Autowired
public void setD1(Demo1 d1) {
    
    
	this.d1 = d1;
}

  2. 可以通过 @Autowired(required = false) 的方式设置为 Spring 容器中,没有对应类型的 bean,就不进行自动装入。

@Autowired(required = false)
public void setD1(Demo1 d1) {
    
    
	this.d1 = d1;
}

  3. 那如果 Spring 容器中,有多个对应类型的 bean 呢?@Autowired 注解按照 byType 方式查找,得到可以赋值的类型的 bean 数目大于 1 时,会按照 byName 方式进行装载,如果按照 byName 方式也找不到一个唯一的 bean,会抛出 bean 不唯一的异常。

   小结:

  1. 使用 @Autowired注解,如果在 Spring 容器中找不到 bean,会抛出异常。
  2. 使用 @Autowired(required = false),如果在 Spring 容器中找不到 bean,不进行自动装载。
  3. 如果找到的合适类型的 bean 不止一个,进行 byName 方法进行查找,如果使用 byName 方式也找不到唯一的一个 bean,抛出不唯一异常。
  4. 第3种情况可以搭配 @Qualifier 注解解决。

  @Autowired 注解放在 set 方法上,如果 set 方法的参数名和属性名不相同,如下面 Demo3 的属性名是 d1,设置这个属性的 set 方法的参数名是 obj1。按照 byType 在 Spring 容器中查找,找到了一个和属性名相同Demo1 类型的 bean —— obj1,找到了一个和参数名相同 Demo1 类型的bean —— name,此时 Autowired 按照 byName 查找时到底会按照属性名还是参数名查找?答:按照 set 方法的参数名查找。

public class Demo3 {
    
    
	private Demo1 d1;
	@Autowired(required = false)
	public void setD1(Demo1 obj1) {
    
    
		this.d1 = obj1;
	}
}
<bean class="model.Demo1" id="obj1" p:name="111"></bean>
<bean class="model.Demo1" id="name" p:name="333"></bean>
<bean class="model.Demo3" id="obj"></bean>
public static void main(String[] args) {
    
    
	String xmlPath = "spring/testAnnotation.xml";
	ApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
	Demo3 d1 = (Demo3) context.getBean("obj");
	System.out.println(d1);
}

  结果:在这里插入图片描述
  

@Qualifier 注解

  Qualifier —— 取得资格的人,合格的人。
  在进行自动装载时,按照类型查找,如果找到了多个 bean,搭配 @Qualifier(“实现类的名字”),指定需要注入的 bean。

@Resource 注解

   Resource 注解常用于和 Autowired 注解对比考察。

@Resource @Autowired
提供厂商 Jdk Spring
使用形式 先 byName,如果处理不了再 byType 先 byType,如果处理不了再 byName

   不带参数时,表示从容器中找到和属性名相同的 bean 注入
   带参数时,表示从容器中找到和参数名相同的 bean 注入给属性

// 从容器中找名为 d1 的 bean 注入给 d1
@Resource
private Demo1  d1;
// 从容器中找名为 obj1 的 bean 注入给 d2
@Resource("obj1")
private Demo1  d2;

@Controller 注解

   Controller —— 控制器。
  @Controller 注解是放在控制层的实现类上,此时,Spring 容器在加载的时候,如果知道 @Controller 注解这个注解在哪里,就会将 @Controller 注解修饰的类的实例放到 Spring 容器中。
  这个过程就 IOC 的过程。
  后面的 @Service 注解、@Repository 注解、@Component 注解都是差不多的

@Service 注解

  @Service 注解是放在业务层实现类上

@Repository 注解

   @Repository 注解是放在数据层实现类上

@Component 注解

   Component —— 组件。
  @Component 注解将其修饰的类的实例交由 Spring 容器处理。
  @Component 注解一般应用于除了控制层、业务层、数据层的实现类之外的类上,一般是在 Spring-Boot 中用的比较多。

使用

  @Controller 注解、@Service 注解、@Repository 注解在使用的时候有两种常用形式,一种不带参数,一种带参数。

@Controller
public class Test1Controller{
    
    }
@Controller("test")
public class Test2Controller{
    
    }

  不带有参数的形式,会将其所修饰的类实例化对象交由 Spring 容器管理,其中实例的名字为类名的首字母小写,如上面代码中的 Test1Controller 类的实例名就是 test1Controller
  带有参数的形式,会将其所修饰的类实例化对象交由 Spring 容器管理,其中实例的名字为参数名,如上面代码中的 Test2Controller 类的实例名就是 test

  最后一个知识点:前面使用@Controller 注解、@Service 注解、@Repository 注解、@Component 注解修饰的类,需要进行扫描才会放入到 Spring 容器中。
  这个扫描操作需要在 Spring 配置文件中进行

<context:component-scan base-package="" />

  这个 XML 标签的作用就是从 base-package 中写的包开始,扫描那些被组件注解修饰的类,扫描到了之后,将这些类解析,创建实例之后,放入到 Spring 容器中。

回顾在 Spring 配置文件中需要写的内容

  1. 命名空间中创建 context 命名空间,并配置 xsi:schemaLocation

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlsn:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
	    http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">
</beans>

  2. 启动注解

<context:annotation-config></context:annotation-config>

  3. 从某个包开始,扫描组件

<context:component-scan base-package="包名">

猜你喜欢

转载自blog.csdn.net/qq_40395874/article/details/114365283