(1). 控制即:资源的获取方式;
(2). 一种为主动式(需要什么资源自己创建即可),一种为被动式(资源不是自己创建,而是交给一个容器来创建和设置);
(3). 容器:管理所有的组件(有功能的类),目的就是把主动的new资源变为被动的接受资源;
(4). 用例子说明就是(容器)婚介所,主动获取变为被动接受;
(1). 容器能知道哪个组件(类)运行的时候,需要另外一个类(组件);容器通过反射的形式,将容器中准备好的对象注入(利用反射给属性赋值)
(2). 只要容器管理的组件,都能使用容器提供的强大功能;
ClassPathXmlApplicationContext(ioc.xml):
ioc容器的配置文件在类路径下(但是。ider的module模块下的src文件夹只会识别class文件,所以,我们的这个应用配置xml文件,就会报错找不到文件)FileSystemXmlApplicationContext("D:\\IderWorkspace_Spring\\src\\ioc.xml");
意思为ioc容器的配置文件在磁盘路径下;(我开始初学用的是这个,建议使用ClassPathXmlApplicationContext(ioc.xml):
)package com.atguigu.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author liuqi
* @create 2020--04--24--22:18
*/
public class Person {
//基本类型直接使用:
// 自动的进行类型转换;
private String lastName="小明";
private Integer age;
private String gender;
private String email;
private Car car;
private List books;
private Map map;
private Properties properties;
//xxxxx
public Person() {
}
public Person(String lastName, Integer age, String gender) {
this.lastName = lastName;
this.age = age;
this.gender = gender;
System.out.println("三个参构造器...age");
}
public Person(String lastName,String email,String gender) {
this.lastName = lastName;
this.gender = gender;
this.email = email;
System.out.println("三个参构造器...email");
}
public Person(String lastName, Integer age, String gender, String email) {
this.lastName = lastName;
this.age = age;
this.gender = gender;
this.email = email;
System.out.println("有参参构造器");
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public List getBooks() {
return books;
}
public void setBooks(List books) {
this.books = books;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
", car=" + car +
", books=" + books +
", map=" + map +
", properties=" + properties +
'}';
}
}
package com.atguigu.bean;
/**
* @author liuqi
* @create 2020--05--15--17:45
*/
public class Car {
private String carName;
private String price;
private String color;
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"carName='" + carName + '\'' +
", price='" + price + '\'' +
", color='" + color + '\'' +
'}';
}
}
package com.atguigu.bean;
/**
* @author liuqi
* @create 2020--05--15--20:37
*/
public class Book {
private String bookName;
private String author;
public void initBook(){
System.out.println("这是initBook()方法,初始化方法");
}
public void destroyBook(){
System.out.println("这是destroyBook()方法,销毁方法");
}
public Book() {
System.out.println("创建book的无参构造方法");
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", author='" + author + '\'' +
'}';
}
}
-->
package com.atguigu.test;
import com.atguigu.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* @author liuqi
* @create 2020--04--24--22:27
*/
public class IOCTest {
private static ApplicationContext ioc = new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\ioc.xml");
/*中文报错意思:初始化程序错误异常,原因就是我用的是文件路径,而其他地方用的时候,由于项目名不一样就会报错,建议使用ClassPathXmlApplicationContext()
java.lang.ExceptionInInitializerError
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [D:\IderWorkspace_Spring\src\ioc.xml]; nested exception is java.io.FileNotFoundException: D:\IderWorkspace_Spring\src\ioc.xml (系统找不到指定的路径。)
*/
//@Test的使用 是该方法可以不用main方法调用就可以测试出运行结果,是一种测试方法
//一般函数都需要有main方法调用才能执行,注意被测试的方法必须是public修饰的
@Test
public void test(){
/*ApplicationContext :容器,配置文件,上下文*/
//ApplicationContext:代表ioc容器(Inversion of Control,缩写为IoC,控制反转)
//ClassPathXmlApplicationContext:当前应用的xml配置文件classpath下;
//根据spring的配置文件得到ioc容器对象;
// ApplicationContext ioc = (ApplicationContext)new ClassPathXmlApplicationContext("src/ioc.xml");
//容器帮我们创建好了对象;
Person person1 = (Person)ioc.getBean("person1");
System.out.println(person1);
}
//实验二:根据bean的类型从IOC容器中获取bean的实例;
@Test
public void test2(){
ApplicationContext ioc02 = new FileSystemXmlApplicationContext("D:\\IderWorkspace_Spring\\src\\ioc.xml");
Person person02 = ioc02.getBean(Person.class);
System.out.println(person02);
//报错:如果IOC容器中同种类型d的bean有多个,报错如下:
// org.springframework.beans.factory.NoUnique(唯一的)BeanDefinition(定义)Exception:
// No qualifying bean of type [com.atguigu.bean.Person] is defined:
// expected single(单个) matching(匹配) bean but found 2: person1,person02
}
//实验二正确方法:(ioc.getBean("person02",Person.class);第一个参数为bean的id标识符,第二个为对象class)
@Test
public void test2True(){
Person person02 = ioc.getBean("person02",Person.class);
System.out.println(person02);
}
//实验三:通过构造器为bean的属性赋值(index,type属性介绍),通过p名称空间为bean赋值;
@Test
public void test3True(){
Object obj = ioc.getBean("person03");
System.out.println(obj);
}
@Test
public void test3TwoTrue(){
/*Object obj2 = ioc.getBean("person03.2");
System.out.println(obj2);
Object obj3 = ioc.getBean("person03.3");
System.out.println(obj3);*/
Object obj4 = ioc.getBean("person03.4");
System.out.println(obj4);
//没写type:三个参构造器...age
//Person{lastName='03.4', age=19, gender='男', email='null'}
//添加type:三个参构造器...email
//Person{lastName='03.4', age=null, gender='男', email='19'}
}
@Test
public void Test4(){
Object person04 = ioc.getBean("person04");
System.out.println(person04);
}
}
/*1、中文报错意思:初始化程序错误异常,原因就是我用的是文件路径,而其他地方用的时候,由于项目名不一样就会报错,建议使用ClassPathXmlApplicationContext()
java.lang.ExceptionInInitializerError
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [D:\IderWorkspace_Spring\src\ioc.xml]; nested exception is java.io.FileNotFoundException: D:\IderWorkspace_Spring\src\ioc.xml (系统找不到指定的路径。)
*/
//2、报错:如果IOC容器中同种类型d的bean有多个,报错如下:
// org.springframework.beans.factory.NoUnique(唯一的)BeanDefinition(定义)Exception:
// No qualifying bean of type [com.atguigu.bean.Person] is defined:
// expected single(单个) matching(匹配) bean but found 2: person1,person02
3、bean标签的id名字与测试文件getBean("id")不一致报错;
报错如下:
org.springframework.beans.factory.NoSuch(如此的)BeanDefinition(定义)Exception:
No bean named 'person044' is defined
4、当创建了有参构造器,在使用bean配置文件的时候,如果报错,必须使用
;不可以使用property和命名空间
说明:你没有写无参构造器;
(相当于,你在实例化对象,new一个无参的对象再set,和new一个有参的对象)
报错如下:( Instantiation of bean failed(bean的实例化失败); nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [com.atguigu.bean.Person]: No default constructor found(未找到默认构造函数);
nested exception(嵌套异常) is java.lang.NoSuchMethodException: com.atguigu.bean.Person.()(初始化))
5、 报错:如果IOC容器中同种类型的bean有多个,报错如下:
org.springframework.beans.factory.NoUnique(唯一的)BeanDefinition(定义)Exception:
No qualifying bean of type [com.atguigu.bean.Person] is defined:
expected single(单个) matching(匹配) bean but found 2: person1,person02
6、来指定id名字;(特别注意:指定类名开头字母小写)
中文解释:bean配置constructor-arg构造元的时候,没有命名时候,变量和值变量不一致报错(不能解决匹配的构造函数,简单参数的参数,以避免类型歧义)
java.lang.ExceptionInInitializerError
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'person03.2' defined in file [D:\iderAllProject\IderWorkspace_Spring\src\ioc.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
解决方法,一一核对变量和变量值的对应关系(或者:index从0开始 为参数指定索引-->)
root
123456
package com.atguigu.test;
import com.atguigu.bean.Book;
import com.atguigu.bean.Car;
import com.atguigu.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import java.util.List;
import java.util.Map;
/**
* @author liuqi
* @create 2020--05--15--20:46
*/
public class IOCTest2 {
ApplicationContext ioc2 = new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\ioc2.xml");
/*private static ApplicationContext ioc2 = new FileSystemXmlApplicationContext("D:\\IderWorkspace_Spring\\src\\ioc2.xml");*/
@Test
public void Test1(){
Person person1 = (Person) ioc2.getBean("person1");
System.out.println(person1.getLastName() == null);
//return true
System.out.println(person1.getCar());
//Car{carName='宝马', price='30000', color='绿色'}
Car car = person1.getCar();
Object car01 = ioc2.getBean("car01");
System.out.println(car01);
System.out.println(car == car01);
// return true
}
@Test
public void Test02(){
Person person01 = (Person) ioc2.getBean("person1");
Car car = person01.getCar();
System.out.println(car);
//Car{carName='单车', price='null', color='null'}
}
@Test
public void Test03(){
Person person03 = (Person) ioc2.getBean("person03");
List books = person03.getBooks();
System.out.println(books);
//没有使用内部bean [Book{bookName='书1', author='null'}, Book{bookName='书3', author='刘奇2'}]
//没有用命名空间 [Book{bookName='书2', author='刘奇'}, Book{bookName='书3', author='刘奇2'}]
//用命名空间同时使用了内部bean会报错
//org.springframework.beans.factory.parsing.BeanDefinitionParsingException: an definition parsing
//Offending resource: file [D:\IderWorkspace_Spring\src\ioc2.xml]Configuration problem: Unexpected failure during be
//Bean 'person03'; nested exception is org.springframework.beans.factory.parsing(解析).BeanDefinitionParsingException: Configuration problem: Property 'bookName' is already defined using both and inline(内联函数) syntax(语法). Only one approach(接近 方法) may be used per(线) property.
//Offending resource: file [D:\IderWorkspace_Spring\src\ioc2.xml]
}
@Test
public void Test04(){
Object ccar = ioc2.getBean("ccar");
System.out.println("---------"+ccar);
// 报错原因是:在bean配置中id为ccar没有被定义;
/*报错代码:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'ccar' is defined
说明:内部bean不能用id获取*/
}
@Test
public void Test05(){
Person bean = (Person)ioc2.getBean("person03");
Map map = bean.getMap();
System.out.println(map);
/*{key01=张三, key02=Book{bookName='书3', author='刘奇2'},
key03=Car{carName='包马', price='null', color='null'}}*/
}
@Test
public void Test06(){
Person person04 = (Person) ioc2.getBean("person04");
Map map = person04.getMap();
System.out.println(map);
}
/*级联属性可以修改属性的属性,注意:原来的bean值也会被修改*/
@Test
public void Test07(){
Person person05 = (Person) ioc2.getBean("person5");
Object o = ioc2.getBean("person5");
Car map = person05.getCar();
System.out.println(map);
System.out.println(o);
}
}
1、用命名空间同时使用了内部bean会报错
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unexpected failure during bean definition parsing
Offending resource: file [D:\IderWorkspace_Spring\src\ioc2.xml]
Bean 'person03'; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Property 'bookName' is already defined using both and inline syntax. Only one approach may be used per property.
Offending resource: file [D:\IderWorkspace_Spring\src\ioc2.xml]
2、引用内部的bean:对象我们可以使用bean创建,相当于 car = new Car();不能被获取到,只能内部使用-
报错,找不到id名字
3、引用util(工具)写名称空间创建集合类型的bean:方便其他bean引用
报错原因:Error:(7, 45) java: 程序包org.graalvm.compiler.core.common.util不存在
解决方法:点击项目名右击--》Maven 专家--》reimport:全部重新导入
4、引用util(工具)写名称空间创建集合类型的bean:方便其他bean引用时候,报错但无法找到元素 'util:map' 的声明。
报错原因:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
Line 93 in XML document from file [D:\IderWorkspace_Spring\src\ioc2.xml] is invalid;
nested exception is org.xml.sax.SAXParseException;
lineNumber: 93; columnNumber: 22; cvc-complex-type.2.4.c:
通配符的匹配很全面, 但无法找到元素 'util:map' 的声明。*/
解决方法:在Spring配置文件中定义util(工具)写名称空间创建集合类型的bean—和相应的schemaLocation(两个)相对应
1.1 MyFactory
package com.atguigu.Factory;
import com.atguigu.bean.Book;
import org.springframework.beans.factory.FactoryBean;
public class MyFactory implements FactoryBean {
//第一个获取对象,并传值
public Book getObject() throws Exception {
Book book = new Book();
book.setBookName("刘奇自传");
book.setAuthor("刘奇");
return book;
}
//获取对象的类型,并返回
public Class> getObjectType() {
return Book.class;
}
//判断对象是否是单实例(true),还是多实例(false)
//单实例:每次创建的对象都是一样的
//多实例:每次创建的对象都是不一样的
public boolean isSingleton() {
return true;
}
}
1.2 **RoomInstanceFactory **
package com.atguigu.Factory;
import com.atguigu.bean.Room;
/**
* @author liuqi
* @create 2020--06--16--8:19
*/
public class RoomInstanceFactory {
public Room RoomsFactory(String dx){
System.out.println("这是实例化建造房间工厂方法");
Room room = new Room();
room.setDx(dx);
room.setCs("2");
room.setGd("10m");
room.setYs("蓝色");
return room;
}
}
1.3 **RoomStaticFactory **
package com.atguigu.Factory;
import com.atguigu.bean.Room;
/**
* @author liuqi
* @create 2020--06--16--8:19
*/
public class RoomStaticFactory {
public static Room getRoom(String dx){
System.out.println("这是静态的建造房间工厂方法");
Room room = new Room();
room.setDx(dx);
room.setCs("3");
room.setGd("20m");
room.setYs("红色");
return room;
}
}
package com.atguigu.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* @author liuqi
* @create 2020--06--15--23:36
*/
public class IOCTest3{
ApplicationContext Ioc = new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\ioc3.xml");
public static void main(String[] args) {
System.out.println("ss");
}
@Test
public void Test1(){
System.out.println("容器完成");
//静态工厂方法在bean配置中声明会自动被调用;
/*完成打印:这是静态的建造房间工厂方法
容器完成*/
}
@Test
public void Test2(){
/* bean配置没有必需的类型异常*/
// org.springframework.beans.factory.BeanNotOfRequiredTypeException:
// Bean named 'room' must be of type [com.atguigu.Factory.RoomStaticFactory],
// but was actually of type [com.atguigu.bean.Room]
Object bean = Ioc.getBean("room");
System.out.println(bean);
/*类转换异常*/
//java.lang.ClassCast(投掷)Exception(类转换异常):
//class com.atguigu.bean.Room cannot be cast to class com.atguigu.Factory.RoomStaticFactory
//(com.atguigu.bean.Room and com.atguigu.Factory.RoomStaticFactory are in unnamed module of loader 'app')
}
@Test
public void Test3(){
Object roomInstanceRealize = Ioc.getBean("RoomInstanceRealize");
System.out.println(roomInstanceRealize);
}
@Test
public void Test4(){
/*Object roomInstanceRealize = Ioc.getBean("MyFactory", MyFactory.class);
System.out.println(roomInstanceRealize);*/
//Ioc.getBean("MyFactory", MyFactory.class);中的参数类型不一致
//org.springframework.beans.factory.BeanNotOfRequiredTypeException:
// Bean named 'MyFactory' must be of type [com.atguigu.Factory.MyFactory],
// but was actually of type [com.atguigu.bean.Book]
Object roomInstanceRealize = Ioc.getBean("MyFactory");
Object roomInstanceRealize2 = Ioc.getBean("MyFactory");
System.out.println(roomInstanceRealize==roomInstanceRealize2);
}
}
8、用的配置文件无效,嵌套异常,无法找到声明;
报错原因:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
Line 26 in XML document from file
[D:\iderAllProject\IderWorkspace_Spring\src\applicationContext03.xml] is invalid(无效的);
nested(嵌套) exception is org.xml.sax.SAXParseException;
lineNumber: 26; columnNumber: 57; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明。
解决方法:在Spring配置文件中定义context命名空间和相应的schemaLocation(两个)相对应
(xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd")
package com.atguigu.Importent;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcess implements BeanPostProcessor {
/*
* 1)、编写后置处理器的实现类;
* 2)、将后置处理器注册在【配置文件中
* */
/*
* postProcessBeforeInitialization:
* 初始化之前调用
* Object bean:将要初始化的bean
* String s:bean在xml中配置的id
* */
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("["+beanName+"]"+"bean将要调用初始化方法了。。BeforeInitialization。"+"这个bean是这样的["+bean+"]");
//返回传入的bean;
return bean;
}
/*
* postProcessAfterInitialization:
* 初始化方法之后调用
* */
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("["+beanName+"]"+"bean初始化方法之后调用完了。。AfterInitialization。"+"这个bean是这样的["+bean+"]");
//初始化之后返回的bean;返回的是什么,容器中保存的就是什么;
return bean;
}
}
package com.atguigu.Importent;
import com.atguigu.bean.Car;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class IocText {
// ApplicationContext applicationContext =new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext.xml");
/*报错原因为:class文件找不到,用File方法一般都能找到*/
// org.springframework.beans.factory.BeanDefinitionStoreException:
// IOException parsing XML document from class path resource [D:/iderAllProject/IderWorkspace_Spring/src/applicationContext.xml];
// nested exception is java.io.FileNotFoundException: class path resource [D:/iderAllProject/IderWorkspace_Spring/src/applicationContext.xml]
// cannot be opened because it does not exist
//实验10:创建带有生命周期方法的bean
//证明:
/*单例Bean的生命周期
(容器启动)构造器----》初始化方法---》(容器关闭)销毁方法(需要写close方法)
多实例Bean的生命周期
(获取bean)构造器----》初始化方法---》容器关闭也会调用bean的销毁方法(需要写close方法)*/
@Test
public void Experiment10 (){
//创建ioc容器的时候,会直接调用init初始化方法:
// (打印为:创建book的无参构造方法
//这是initBook()方法,初始化方法)
ConfigurableApplicationContext configurableApplicationContext =new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext.xml");
Object book01 = configurableApplicationContext.getBean("book01");
System.out.println("关闭了");
// configurableApplicationContext.close();
}
@Test
public void Experiment10two (){
ConfigurableApplicationContext configurableApplicationContext =new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext.xml");
Object book02 = configurableApplicationContext.getBean("book02");
System.out.println("Experiment10two ()关闭了");
// configurableApplicationContext.close();
/*创建book的无参构造方法
这是initBook()方法,初始化方法
Experiment10two ()关闭了
这是destroyBook()方法,销毁方法*/
}
//实验11:测试bean的后置处理器:BeanPostProcessor
//证明1:什么都不写,直接实现ioc容器,为:单实例会执行,多实例不会执行
/*后置处理器的生命周期
(容器启动)构造器----》后置处理器(postProcessBeforeInitialization)----》初始化方法---》后置处理器(postProcessAfterInitialization)----》bean初始化完成*/
//证明2:多实例执行,除非是用ioc容器获取了它才会执行
/*后置处理器的生命周期
(获取bean)构造器----》后置处理器(postProcessBeforeInitialization)----》初始化方法---》后置处理器(postProcessAfterInitialization)----》bean初始化完成*/
@Test
public void BeanPostProcessorTest(){
//结果为:
/* 创建book的无参构造方法
[book01]bean将要调用初始化方法了。。BeforeInitialization。这个bean是这样的[Book{bookName='null', author='null'}]
这是initBook()方法,初始化方法
[book01]bean初始化方法之后调用完了。。AfterInitialization。这个bean是这样的[Book{bookName='null', author='null'}]*/
}
//实验11:测试bean的后置处理器:BeanPostProcessor
//证明3:无论bean是否有初始化方法;后置处理器都会默认其有,还会继续工作;
@Test
public void CarTest1(){
ConfigurableApplicationContext configurableApplicationContext =new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext.xml");
/*
结果为:
[car01]bean将要调用初始化方法了。。BeforeInitialization。这个bean是这样的[Car{carName='null', price='null', color='null'}]
[car01]bean初始化方法之后调用完了。。AfterInitialization。这个bean是这样的[Car{carName='null', price='null', color='null'}]
*/
}
@Test
public void CarTest02(){
ApplicationContext ioc = new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext02.xml");
Car car = ioc.getBean("car01", Car.class);
System.out.println(car);
//Car{carName='null', price='null', color='null'}
}
}
package com.atguigu.Service;
import com.atguigu.Dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void save(){
System.out.println("bookservice....正在调用Dao保存图书");
bookDao.saveBook();
}
}
(2)BookServiceExt.class
package com.atguigu.Service;
import org.springframework.stereotype.Service;
@Service
public class BookServiceExt extends BookService {
@Override
public void save(){
System.out.println("BookServiceExt......");
}
}
package com.atguigu.Servlet;
import com.atguigu.Dao.BookDao;
import com.atguigu.Service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
/*@Autowired:Spring会自动的为这个属性赋值;
一定是去容器中找到这个属性对应的组件*/
@Controller
public class BookServlet {
/*servlet(控制器)*/
/*自动装配*/
/*@Qualifier(限定符 限定词 修饰符):指定一个名作为id,让spring别使用变量名作为id(前提是已经由@autowired注解查找属性时有多个)
* 特别注意:指定类名开头字母小写*/
@Qualifier("bookServiceggg")
//这里多个BookService的本类和继承类,但是没有一个类名是bookServiceggg,所以,找不到,会报空指针异常;
// 然后,又@Autowired(required=false),设置为false之后,没有强制去自动配置,如果找到则继续,没找到不会报错,变量为null
@Autowired(required=false)
private BookService bookServiceExt2;
public void get(){
//bookServiceExt2.save();
System.out.println(".........使用required = false"+bookServiceExt2);
/*结果为:.........使用required = false null*/
}
/*
* 方法上有@Autowired的话;
* 1、这个方法也会在bean创建的时候自动运行
* 2、这个方法上的每一个参数都会自动注入值
*
* */
/*里面的变量和变量名一样遵循@Autowired原理:*/
@Autowired
public void BookTest(BookDao bookDao, @Qualifier("bookServiceExt") BookService bookService){
System.out.println("当bean创建的时候自动运行"+bookDao+"---->"+bookService);
}
}
package com.atguigu.Dao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
/**/
@Repository("bookdaohh")
@Scope(value = "prototype")
//作用域为多实例
public class BookDao {
/*Repository:资源库,仓库*/
public void saveBook(){
System.out.println("图书已经保存");
}
}
来进行扫描基础包来运行自动配置
package com.atguigu.test;
import com.atguigu.Service.BookService;
import com.atguigu.Servlet.BookServlet;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/*
*目的是:创建变量并给它一个@Autowired自动装配,在一个方法里面可以直接用(不用写ioc容器和ioc.get)
* 使用Spring的单元测试;
* 1、导包:Spring单元测试包spring-test-4.0.0.RELEASE.jar
* 2、@ContextConfiguration(locations ="")使用它来指定Spring的配置文件的位置
* 3、@RunWith指定用哪种驱动进行单元测试,默认就是junit
* @RunWith(SpringJUnit4ClassRunner.class)
* 使用Spring的单元测试模块来执行标了@Test注解的测试方法;
* 以前的@Test注解只是由junit执行
*好处:我们不用ioc.getbean()获取组件了;直接Autowired组件,Spring为我们自动装配
* */
//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = "classpath:applicationContext03.xml")
/*严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@3e6fa38a] to prepare test instance [com.atguigu.test.IOCTest4@66a3ffec]
java.lang.IllegalStateException: Failed to load ApplicationContext*/
public class IOCTest4 {
ApplicationContext ioc = new FileSystemXmlApplicationContext("D:\\iderAllProject\\IderWorkspace_Spring\\src\\applicationContext03.xml");
// ApplicationContext ioc = null;
private BookService bookService;
private BookServlet bookServlet;
@Test
public void UnitTest1(){
System.out.println("bookService=="+bookService+","+"bookServlet=="+","+bookServlet);
}
/*使用注解加入到容器中的组件,和使用配置加入到容器中的组件行为都是默认一样的;
1、组件的id,默认就是组件类名的首字母小写
@Repository("别名")
@Repository("bookdaohh")
2、组件的作用域,默认就是单例的;
@Scope("prototype")*/
@Test
public void AnnotationTest1(){
/*注解Annotation comment Note*/
Object bookDao = ioc.getBean("bookdaohh");
Object bookDao2 = ioc.getBean("bookdaohh");
System.out.println(bookDao == bookDao2);
/*返回true是单实例*/
}
@Test
public void AutowiredTest1(){
BookServlet bookServlet = (BookServlet)ioc.getBean("bookServlet");
bookServlet.get();
}
@Test
public void AutowiredTest2(){
/*@Autowired自动装配注解可以放在方法上面*/
/*打印结果为:当bean创建的时候自动运行com.atguigu.Dao.BookDao@a3d8174---->com.atguigu.Service.BookService@1ba9117e*/
}
}
1、用的配置文件无效,嵌套异常,无法找到声明;
报错原因:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
Line 26 in XML document from file
[D:\iderAllProject\IderWorkspace_Spring\src\applicationContext03.xml] is invalid(无效的);
nested(嵌套) exception is org.xml.sax.SAXParseException;
lineNumber: 26; columnNumber: 57; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明。
解决方法:在Spring配置文件中定义context命名空间和相应的schemaLocation(两个)相对应
(xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd")
2、中文解释:创建bean配置异常,不能自动装配private com.atguigu.Service.BookService com.atguigu.Servlet.BookServlet.bookServiceExt2;
在自动装配的时候有两个一样的变量,但是配置变量名bookServiceExt2异常
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'bookServlet':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.atguigu.Service.BookService com.atguigu.Servlet.BookServlet.bookServiceExt2;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.atguigu.Service.BookService] is defined: expected single matching bean but found 2: bookService,bookServiceExt
解决办法;面对这种情况,有两个一样的变量,则使用@Qualifier:指定一个名作为id,让spring别使用变量名作为id(前提是已经由@autowired注解查找属性时有多个)
这里就把基本的bean配置和到注解实验验证完毕;后面开始就需要学习AOP了哦!
如有不懂可以加我并练习哦;
个人也有免费大学生毕业网站和答辩项目总集;
并提供免费软件和教学视频;
QQ+2545062785
此文章的一部分图片和所用学习笔记,学习历程来源于B站的UP主雷Java-spring-springmvc-mybatis-雷丰阳版-ssm一站式学习-尚硅谷,点击该段话,跳转视频地址
把此作为笔记,如有侵权或者不允许截图等,会马上删除的,谢谢!
以上总结,当采纳和对你有帮助时;
留下你的点赞足迹+你爱心的评论哦!
(⓿_⓿)谢啦!!☆⌒(*^-゜)v