Spring 通过注解的方式配置bean与bean之间的关系

版权声明:博客知识产权来源命运的信徒,切勿侵权 https://blog.csdn.net/qq_37591637/article/details/85157761

这篇博客是在https://blog.csdn.net/qq_37591637/article/details/85156536   这个基础上讲述的


当一个类中有另一个类的属性的时候,在这个类利用另一个类的属性去调另一个类的方法,如果没有set和get方法,就会报空指针异常;

注解提供了自动装配的功能帮我们解决了这个问题


@Autowired 注解自动装配具有兼容类型的单个 Bean属性
构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解

前提是都被注解了

以下是这个包下面的代码

package cn.com.bean.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import cn.com.bean.service.ServicesTest;
@Controller(value="Controllers")
public class ControllerClass  implements ControllInter{
	/*当一个类中有另一个类的属性的时候,在这个类利用另一个类的属性去调另一个类的方法
	 * 如果没有set和get方法,就会报空指针异常;
	 * 注解提供了自动装配的功能帮我们解决了这个问题@Authwired 
	 */
@Autowired
private ServicesTest se;
	
	@Override
	public void save() {
		// TODO Auto-generated method stub
		System.out.println("标识表现层组件--我实现了ControllInter接口的save方法....");
		se.sevice();
	}

}
package cn.com.bean.controller;

public interface ControllInter {
void save();
}

 

package cn.com.bean.Respository;

import org.springframework.stereotype.Repository;
@Repository(value="res")
public class TRespository {
public void respon(){
	System.out.println("标识持久层组件.....");
}
}

 

package cn.com.bean.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.com.bean.Respository.TRespository;
@Service
public class ServicesTest {
	@Autowired
	private TRespository cc;
	public void sevice() {

		System.out.println("标识服务层(业务层)组件....");
		cc.respon();
	}
}

 测试类如下

package cn.com.bean;

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

import cn.com.bean.controller.ControllerClass;

public class TestMain {
	/*
	 * author:命运的信徒 date:2018/12/21 arm:注解的方式来配置bean与bean之间的关系
	 */
	public static void main(String[] args) {
		// 1.创建IOC容器
		ApplicationContext ioc = new ClassPathXmlApplicationContext(
				"bean-bean.xml");
		// 2.
		ControllerClass cc = (ControllerClass) ioc.getBean("Controllers");
		cc.save();
	}
}

配置文件bean-bean.xml

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="cn.com.bean">

</context:component-scan>

</beans>

结果如下

自动装配是不是省了很多的set和get方法呢?

不过这上面的实现都是在Spring文件被扫描过的,也就是文件上面有一个S的标志,如果是调用普通的类里面的方法的话,怎么办呢》

继续往下看


默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false

例如在这个类中使用非注解类

package cn.com.bean.Respository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import cn.com.bean.Common;
@Repository(value = "res")
public class TRespository {
	@Autowired(required=false)
	private Common sc;
	public void respon() {
		System.out.println("标识持久层组件.....");
		System.out.println(sc);
	}
}

非注解类

package cn.com.bean;

public class Common {
	public void cm() {
		System.out.println("我就是一个普通的没有被注解的类的方法...");
	}
}

 运行结果不会报错,结果:

标识持久层组件.....

null

我只是觉得奇怪,为什么非要打印类名sc,难道不能调用sc.cm()方法么,打印出cm()方法里面的话?

事实是不能这样做,会报空指针异常!

我想加了注解@Autowired的作用就是相当于给这个属性初始化了;

而只有注解文件之间才可以相互调用方法,注解文件和非注解文件之间的方法是调不得的!尽管设置@Authwired 注解的 required 属性为 false,也仅仅是不报错而已,如果有其他的见解可以评论我!


默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称

这句话什么意思???

例如A类、B类都继承一个接口C,在一个注解类D中调用这个C接口类型的方法,这个时候调用就会报错,

因为匹配是唯一的;

No qualifying bean of type [cn.com.bean.controller.ControllInter] is defined: expected single matching bean but found 2: controllerClass,controllerJdbc

那么只需要在D中设置

@Qualifier("controllerJdbc")里面是bean的名称就可以了

demo如下

 

controllerClass,controllerJdbc都继承了ControllInter

在CompentClass里面有一个ControllInter类型的,我们都知道这个类型的类有两个,如果没有用@Qualifier("controllerJdbc")bean名称来识别的话,就会报错,

package cn.com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import cn.com.bean.controller.ControllInter;
@Component
public class CompentClass {
@Autowired
@Qualifier("controllerJdbc")
private ControllInter in;
public void text(){	
	System.out.println("我是受Spring管理的基类....");
	in.save();
}
}

猜你喜欢

转载自blog.csdn.net/qq_37591637/article/details/85157761