一、Spring基础 --- 基础内容(一) (咕P4)

2024-04-09 18:20
文章标签 java 基础 内容 spring p4

本文主要是介绍一、Spring基础 --- 基础内容(一) (咕P4),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Spring简介

1 来源

Struts与Hibernate可以做什么事?

	Struts:Mvc中控制层解决方案 可以进行请求数据自动封装、类型转换、文件上传、效验…Hibernate:持久层的解决方案; 可以做到,把对象保存到数据库, 从数据库中取出的是对象。

传统的开发模式、开发流程

	传统的开发模式:基于mvc模式进行项目开发
基于mvc的项目框架结构:Entity / dao / service / action// 1. 实体类class User{}//2. daoclass  UserDao{.. 访问db}			//3. serviceclass  UserService{UserDao userDao = new UserDao();}//4. actionclass  UserAction{UserService userService = new UserService();..拿到数据或结果}用户访问:/user.action ---->  Tomcat  (服务器创建ActionService、dao

思考

	思考:1. 对象创建创建能否写死?2. 对象创建细节对象数量action  多个   【维护成员变量】service 一个   【不需要维护公共变量】dao     一个   【不需要维护公共变量】创建时间action    访问时候创建service   启动时候创建dao       启动时候创建3. 对象的依赖关系action 依赖 serviceservice依赖 dao=======================================================总结:spring就是解决上面的问题的!简单来说,就是处理对象的创建的、以及对象的依赖关系!

2 spring概念

	官网地址 :http://www.spring.io

在这里插入图片描述

1.1 作用

	作用:简化Java开发的。Spring不仅只是一个框架,Spring已经成为了一种生态。(与其说是Java开发,不如说是Spring开发)Spring可以做非常多的事情,但归根结底,支撑Sprine的仅仅是少许的基本理念,所有的理念都可以追溯到Sprine最根本的使命上!简化java开发。这是一个郑重的承诺。许多框架都声称在某些方面做了简化,但Spring的目标是致力于全方位的简化java开发。这势必引出更多的解释,Spring是如何简化Java开发的?为了降低Java开发的复杂性,Spring采取了以下4种关键策略:1、基于POI0的轻量级和最小侵入式编程;2、通过控制反转和依赖注入以及面向接口实现松耦合;3、基于切面和惯例进行声明式编程:4、通过切面和模板减少样板式代码,

1.2 历史来源

	EJB历史:一个java应用层程序,是由许多个类组成的,这些类之间必然存在依赖关系,当项目越来越大,依赖关系越来越复杂,需要一个专业的框架来处理类之间的依赖关系,为了解决这个问题,SUN公司推出了EJB(重量级)专门用来解决类的依赖问题。Spring历史:Spring (Spring Framework)是一个开源框架,最早由Rod johnson创建,并在《Expert One-on-One:.J2EE Design andDevelopment》这本著作中进行了介绍。解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。但Spring不仅仅局限于服务器端开发,任何java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。

1.3 Spring专有名词

	+++ 组件/框架设计1)侵入式设计引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。例如:	Struts框架(使用struts的校验功能,必须继承ActionSupport,这是一种侵入式设计)2)非侵入式设计引入了框架,对现有的类结构没有影响。例如:Hibernate框架 / Spring框架3)区别侵入式、非侵入式的要点是:引入该框架是否要继承某个特定类。如:引入struts框架,如果要实现校验功能,action必须要继承ActionSupport,这是侵入式设计,所以struts是侵入式框架。引入hibernate,虽然配置了xml配置文件,但是dao无须继承什么类。所以hibernate是非侵入式设计。
+++ 控制反转(IOC)和依赖注入(DI)1) Inversion on Control , 控制反转 IOC对象的创建交给外部容器完成,这个就做控制反转.2) dependency injection 处理对象的依赖关系区别:控制反转, 解决对象创建的问题 【对象创建交给别人】依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】先有控制反转,再有依赖注入,(一个流程步骤)
	+++ AOP面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。切面举例:事务、日志、权限;
	+++ bean的各种名称:虽然Spring用bean或者javaBean来表示应用组件,但并不意味着Spring组件必须要遵循JavaBean规范。一个Spring组件可以是任何形式的POJO(POJO (Plain Ordinaryjava Obiect)简单的java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称)

3 spring-frameworek框架

3.1 地位

spring framework是整个spring中最核心的一个部分。其他项目均是基于该项目进行开发或拓展的。
在这里插入图片描述

3.2 核心模块

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.2 结构图

1、spring-framework是一个工程(框架),里面有许多模块。每一个模块对应一个jar。比如beans、context等。2、没有【spring-all】这个jar。如果想使用,则必须一个一个引入。3、spring核心模块:core、beans、context、sprl。4、如果想使用spring,则必须引入这四个核心jar(core、beans、context、spel,有的版本还需引入日志jar)。

在这里插入图片描述

各个模块之间的依赖关系图

在这里插入图片描述

4 环境准备

4.1 spring-framework版本号说明

spring下载时
在这里插入图片描述

版本说明
在这里插入图片描述

在这里插入图片描述

4.2 jar包下载

官网下载教程https://blog.csdn.net/m0_52861000/article/details/128883819jar包下载地址(注意:没找到release库,只找到了SNAPSHOT库):https://repo.spring.io/ui/native/snapshot/org/springframework/spring/
	下载jar包说明:	   1、spring framework框架是一个工程,里面有许多模块,如core、beans、context等。2、spring各个版本中:1)在3.0以下的版本,源码有spring中相关的所有包【spring功能 + 依赖包】,如2.5版本;2)在3.0以上的版本,源码中只有spring的核心功能包【没有依赖包】(如果要用依赖包,需要单独下载!)3、下载spring framework框架时候,实质上是一个zip压缩包。压缩包里面有zip、api文档、文档约束。而zip中有该spring版本对应的模块(core、beans、context等jar)。【不存在一个包含所有模块的jar】3、maven依赖引入spring framework框架时,没有spring-all坐标,只有具体的模块的坐标。所以只能一个模块一个模块的引入。
1、不存在一个包含所有模块的jar

在这里插入图片描述

2、下载讲解

spring 库
在这里插入图片描述

在这里插入图片描述

4.3 基础案例

引入jar文件

1) 源码, jar文件:spring-framework-3.2.5.RELEASEcommons-logging-1.1.3.jar           日志spring-beans-3.2.5.RELEASE.jar        bean节点spring-context-3.2.5.RELEASE.jar       spring上下文节点spring-core-3.2.5.RELEASE.jar         spring核心功能spring-expression-3.2.5.RELEASE.jar    spring表达式相关表以上是必须引入的5个jar文件,在项目中可以用户库管理!

在org/jsoft/demo引入applicationContext.xml(或bean.xml)配置文件

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><bean id="user"  class="org.jsoft.a_hello.User"></bean></beans>   

创建实体

public class User {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

测试

public class App {@Testpublic void testIOC() {//加载配置文件,创建Bean工程Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);//获取对象User u=(User) factory.getBean("user");System.out.println(u.getAge());}@Testpublic void testIOC2() {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");//获取对象User u=(User) ac.getBean("user");System.out.println(u.getAge());}
}

5 spring注解驱动发展

在这里插入图片描述
在这里插入图片描述

6 IOC、DI

在这里插入图片描述

IOC控制反转:本质上就是将程序中原本手动创建的对象,交给spring容器去处理。
【举例:我吃包子,需要买面、油等,然后手动做。但是我如果直接去包子铺买,就省去很多事情。spring容器就是包子铺(Spring Ioc就是包子铺,对象就是包子。)】

二、基于XML配置方式的实现

1 基础环境搭建

1)新建java项目

在这里插入图片描述

2)导入相关的jar包

创建bin文件夹,然后复制spring框架中的lib核心包(core、beans、context、spel)
在这里插入图片描述
将bin文件夹设置为library库
在这里插入图片描述

3)创建spring配置文件

在src目录下创建applicationContext.xml配置文件
注意:通过该方法创建配置文件,必须使用idea的正式版本,idea的社区版本不能之间创建xml。

在这里插入图片描述
在这里插入图片描述

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>
4)创建对应的java类
package com.hlp.spring.ioc.beans;public class Car {private  String name;private String id;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}
}
5)配置文件中注册bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 通过bean标签将car实例创建--><bean class="com.hlp.spring.ioc.beans.Car"></bean></beans>

在这里插入图片描述

6)java代码实现

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = ac.getBean(Car.class);System.out.println(car);}
}

注意第一次启动抛 ClassNotFoundException异常,因为缺少logging依赖,导入即可
在这里插入图片描述

2 IOC容器

2.1 基于XML创建IOC容器

1)方式一: BeanFactory
	方式一:Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);
	@Testpublic void testIOC() {//加载配置文件,创建Bean工程Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");BeanFactory factory=new XmlBeanFactory(rs);//获取对象User u=(User) factory.getBean("user");System.out.println(u.getAge());}
2)方式二: ApplicationContext
	ClassPathXmlApplicationContext作用:加载classpath根目录下的配置文件,创建IOC容器。1、加载一个配置文件。然后创建IOC容器。加载classpeth根类路径下ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");加载指定类路径下ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");2、加载多个配置文件。然后创建IOC容器。ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml","app2.xml");
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = ac.getBean(Car.class);System.out.println(car);}}

2.2 BeanFactory和ApplicationContext的区别

	ApplicationContext、BeanFactory都是IOC容器。ApplicationContext是BeanFactory的子接口。ApplicationContext功能肯定比BeanFactory的功能更强大。ApplicationContext容器在初始化的时候,就会初始化Bean。而BeanFactory容器中的Bean是懒加载,在初始化的时候,不会初始化Bean,只有在调用getBean时,才会创建对象。

在这里插入图片描述

2.3 容器相关方法

1)一般方法
public static void main(String[] args) {//1.创建IOC容器ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/g_transaction_detail/applicationContext.xml");//2.根据名称获取bean对象DeptDao deptDao=(DeptDao) ac.getBean("deptDao");		//强制转换DeptDao deptDao2 = ac.getBean("deptDao", DeptDao.class);//利用了泛型,无需转换//3.根据类型获取bean对象(该类型只能在容器中有唯一的对象,否则报错)DeptDao deptDao3 = ac.getBean(DeptDao.class);//4.获取容器中bean对象的个数int num = ac.getBeanDefinitionCount();//5.获取容器中所有bean的名字String[] beanDefinitionNames = ac.getBeanDefinitionNames();}
2)getBeans( ) 方法

根据name获取

    <bean class="com.hlp.spring.ioc.beans.Car" name="myCar"></bean>
    public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}

根据id获取

    <bean class="com.hlp.spring.ioc.beans.Car" name="myCar" id="myCar2"></bean>
    public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}

根据class文件获取

    <bean class="com.hlp.spring.ioc.beans.Car" ></bean>
    public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean(Car.class);System.out.println(car);}

如果我们根据类型去容器中获取对象,如果该类型在容器中有多个实例,那么会抛出异常信息
在这里插入图片描述
这时,我们可以根据组合的方式去查找

组合方式查找

    <bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean><bean class="com.hlp.spring.ioc.beans.Car"  ></bean>
    public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car",Car.class);System.out.println(car);}

3 Bean的实例化

		SpringIOC容器,是spring核心内容。作用: 创建对象 & 处理对象的依赖关系
		IOC容器创建对象, 有几种方式:1) 调用无参数构造器2) 带参数构造器3) 工厂创建对象工厂类,静态方法创建对象工厂类,非静态方法创建对象

3.1 Bean标签

<bean>:用于配置对象,让spring来创建。默认情况下调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。class:指定类的全限定类名,用于反射创建对象,默认情况下调用无参构造函数。如果不进行配置并且类中没有无参构造方法,则会创建失败。id:给对象在容器中提供一个唯一标识,用于获取对象。name: 设置别名,在BeanFactory的getBean(“name”)中可以获取相应的bean。scope:指定对象的作用范围singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象prototype:多例的,调用getbean方法时候创建request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 sessioninit-method:指定类中的初始化方法名称destroy-method:指定类中销毁方法名称autowire:自动装配属性byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入default:默认值,不自动装配

3.2 Bean的实例化

3.2.1 构造函数
	1、使用无参构造创建对象(实例对象必须有无参构造)<bean class="com.hlp.demo02.User" id="user"></bean>2、使用有参构造创建对象(实例对象必须有有参构造)<bean class="com.hlp.demo02.User" id="user"><constructor-arg name="name" value="张三"></constructor-arg><constructor-arg name="age" value="123"></constructor-arg></bean>        		
3.2.2 自定义工厂实例化
1)静态工厂创建对象

通过工厂类的静态方法获取对应的实例对象

MyBeanFactory静态工厂

public class MyBeanFactory {public static Car  getInstance1(){return  new Car();}
}

applicationContext-static.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 静态工厂配置--><bean class="com.hlp.spring.ioc.MyBeanFactory"  factory-method="getInstance1"  id="myFactory"></bean>
</beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");Car car = (Car)ac.getBean("myFactory");System.out.println(car);}
}

在这里插入图片描述

2)动态工厂创建对象

通过工厂类的方法获取对应的实例对象
MyBeanFactory工厂

public class MyBeanFactory {public  Car  getInstance1(){return  new Car();}
}

applicationContext-static.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 注册动态工厂--><bean class="com.hlp.spring.ioc.MyBeanFactory"  id="myFactory"></bean><!-- 从工厂中获取car对象--><bean factory-bean="myFactory" factory-method="getInstance1"  id="xxxx"></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-static.xml");Car car = (Car)ac.getBean("xxxx");System.out.println(car);}
}
3.2.3 FactoryBean工厂实例化
1)FactoryBean介绍
1、FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。2、Spring为什么使用FactoryBean一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring 为此提供了一个 org.Springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 bean 的逻辑。3、FactoryBean允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。同时,Spring框架还提供了一些内置的FactoryBean实现,例如ProxyFactoryBean和JndiObjectFactoryBean,可以帮助我们更方便地创建一些常见的Bean实例。
2)FactoryBean接口
1getObject()方法:获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。2getObjectType()方法获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。3isSingleton()方法判断由此工厂创建的对象实例是否为单例模式。默认情况下,FactoryBean创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。4FactoryBeanSpring中的作用当配置文件中< bean>class 属性配置的实现类是 FactoryBean 时,通过 getBean()方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象。相当于FactoryBean#getObject()代理了 getBean()方法。

public interface FactoryBean<T> {// 获取由此工厂创建的对象实例T getObject() throws Exception;// 获取由此工厂创建的对象实例的类型Class<?> getObjectType();// 判断由此工厂创建的对象实例是否为单例模式default boolean isSingleton() {return true;}
}
3)FactoryBean使用

User.java

public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}...}

UserFactoryBean .java

public class UserFactoryBean implements FactoryBean<User> {public User getObject() throws Exception {User user=new User("张三",12);return user;}public Class<?> getObjectType() {return User.class;}public boolean isSingleton() {return false;}
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.UserFactoryBean" id="factoryBean"></bean></beans>

App.java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("factoryBean",User.class);System.out.println(user.getName());System.out.println(user.getAge());}
}

在这里插入图片描述

4)FactoryBean使用场景

1、动态创建对象

public class MyFactoryBean implements FactoryBean<Object> {@Overridepublic Object getObject() throws Exception {// 根据配置或条件动态创建对象if (someCondition) {return new MyObject();} else {return new AnotherObject();}}@Overridepublic Class<?> getObjectType() {// 返回实际创建的对象的类型return Object.class;}@Overridepublic boolean isSingleton() {// 返回是否为单例对象return true;}
}

2、对象的装配和初始化

public class MyFactoryBean implements FactoryBean<MyObject> {private String name;private int age;@Overridepublic MyObject getObject() throws Exception {// 创建对象并进行装配和初始化MyObject myObject = new MyObject();myObject.setName(name);myObject.setAge(age);return myObject;}@Overridepublic Class<?> getObjectType() {return MyObject.class;}@Overridepublic boolean isSingleton() {return true;}// 设置属性值的方法public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}

3、对象的代理和包装

public class MyFactoryBean implements FactoryBean<MyObject> {private MyObject target;@Overridepublic MyObject getObject() throws Exception {// 对目标对象进行代理和包装MyObjectProxy proxy = new MyObjectProxy(target);return proxy.getProxy();}@Overridepublic Class<?> getObjectType() {return MyObject.class;}@Overridepublic boolean isSingleton() {return true;}// 设置目标对象的方法public void setTarget(MyObject target) {this.target = target;}
}

3.3 其他注意事项

	1、bean的名称在IOC容器不可重复。2、使用bean标签配置bean。默认bean的名称为类路径。<bean class="com.hlp.spring.ioc.beans.Car" ></bean>ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");3、使用bean标签配置bean。可以使用id或name配置bean的名称。name配置bean的名称,可以配置多个名称。id配置bena的名称,只能配置一个。1)bean属性的id和name,是bean的唯一标识。2)同一个spring的配置文件中,不同bean的id和name是不能相同的。否则会报错。3)不同的spring配置文件中,id和name可以重复。此时spring针对相同的id或name采取的策略是根据DefaultListableBeanFactory类中的allowBeanDefinitionOverriding属性值来判断的。默认为true,即相同的id或name会被覆盖。如果设置为false,则会抛出异常。
1)使用bean标签配置bean。默认bean的名称为类路径。

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!--  默认bean的名称为'com.hlp.spring.ioc.beans.Car'  --><bean class="com.hlp.spring.ioc.beans.Car" ></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("com.hlp.spring.ioc.beans.Car");System.out.println(car);}
}
2)使用bean标签配置bean。可以使用id或name配置bean的名称。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!--      &lt;!&ndash;  使用name、id均可为bean命名。  &ndash;&gt;--><bean class="com.hlp.spring.ioc.beans.Car"  name="car1" id="car2" ></bean><bean class="com.hlp.spring.ioc.beans.Car"  name="car3"  ></bean></beans>
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car1");System.out.println(car);Car car2 = (Car)ac.getBean("car2");System.out.println(car);}
}
3)使用bean标签配置bean。name可以同时配置多个名称,id只能配置一个名称。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!--  默认bean的名称为'com.hlp.spring.ioc.beans.Car'  -->
<!--      <bean class="com.hlp.spring.ioc.beans.Car" ></bean>--><!--      &lt;!&ndash;  使用name、id均可为bean命名。  &ndash;&gt;--><bean class="com.hlp.spring.ioc.beans.Car"  name="car1,car2,car3"  ></bean></beans>

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car1");System.out.println(car);Car car2 = (Car)ac.getBean("car2");System.out.println(car);}
}

4 Bean的依赖注入(DI)

DI:依赖注入(Dependency Injection)。 是 spring 框架核心IOC的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。
IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

这种业务层和持久层的依赖关系,在使用 spring 之后,让 spring 来维护。
简单的说,就是坐等框架把持久层对象传入业务层,而不用自己去获取。

4.1 构造注入

构造注入:通过构造方法实现属性的注入。第一步需要添加对应的有参构造方法,第二步在配置文件中添加对应的配置信息。方式一:<bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg name="id" value="1111"></constructor-arg><constructor-arg name="name" value="宝马xxx"></constructor-arg><constructor-arg name="age" value="1"></constructor-arg></bean>方式二:<bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg index="0" value="1111"></constructor-arg><constructor-arg index="1" value="宝马xxx"></constructor-arg><constructor-arg  value="1"></constructor-arg></bean>方式三:【使用c标签,需引入c标签约束】<bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>方式四:【使用c标签,需引入c标签约束】<bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean>
1)构造注入

car.java


public class Car {private String id;private  String name;private int  age;public Car(String id, String name, int age) {this.id = id;this.name = name;this.age = age;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg name="id" value="1111"></constructor-arg><constructor-arg name="name" value="宝马xxx"></constructor-arg><constructor-arg name="age" value="1"></constructor-arg></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
2)构造注入

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>--><bean class="com.hlp.spring.ioc.beans.Car" id="myCar" ><constructor-arg index="0" value="1111"></constructor-arg><constructor-arg index="1" value="宝马xxx"></constructor-arg><constructor-arg  value="1"></constructor-arg></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
3)构造注入-c简化【使用c标签简化】

applicationContext.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:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>--><!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg index="0" value="1111"></constructor-arg>-->
<!--        <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg  value="1"></constructor-arg>-->
<!--    </bean>--><bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
4)构造注入-c简化【使用c标签简化】

applicationContext.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:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg name="id" value="1111"></constructor-arg>-->
<!--        <constructor-arg name="name" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg name="age" value="1"></constructor-arg>-->
<!--    </bean>--><!--    <bean class="com.hlp.spring.ioc.beans.Car" id="myCar" >-->
<!--        <constructor-arg index="0" value="1111"></constructor-arg>-->
<!--        <constructor-arg index="1" value="宝马xxx"></constructor-arg>-->
<!--        <constructor-arg  value="1"></constructor-arg>-->
<!--    </bean>--><!--    <bean class="com.hlp.spring.ioc.beans.Car" c:id="11" c:name="宝马xxx" c:age="12" id="myCar" ></bean>--><bean class="com.hlp.spring.ioc.beans.Car" c:_0="11" c:_1="宝马xxx" c:_2="12" id="myCar" ></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}

4.2 设值注入(set赋值)

	通过set方法给属性赋值:<bean id="user"  class="org.jsoft.c_property.User"><!-- 【setAge1111 -》age11111】	 --><property name="age1111" value="12"></property></bean>切记:给实体类赋值,实质上是调用了实体类的的setXXX方法。【如果方法名称为setAge1111,则设置bean的属性时,属性名称为age11111】所以实体类赋值的变量必须有set方法,否则报错。【实体类赋值的成员变量,必须有set方法】		
1)设值注入

Car.java


public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 设值注入:方式一 --><bean class="com.hlp.spring.ioc.beans.Car"  id="car"><property name="id" value="12xxxx"></property><property name="age" value="12"></property><property name="name" value="12"></property></bean><!-- 设值注入:方式二 -->
<!--        <bean class="com.hlp.spring.ioc.beans.Car"  id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean>--></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("myCar");System.out.println(car);}
}
2)设值注入-p标签简化【必须引入p标签】

applicationContext.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 设值注入:方式一 -->
<!--        <bean class="com.hlp.spring.ioc.beans.Car"  id="car">-->
<!--            <property name="id" value="12xxxx"></property>-->
<!--            <property name="age" value="12"></property>-->
<!--            <property name="name" value="12"></property>-->
<!--        </bean>--><!-- 设值注入:方式二 --><bean class="com.hlp.spring.ioc.beans.Car"  id="car2" p:id="xxx" p:age="12" p:name="宝马xxx"></bean></beans>

4.3 赋值方式(根据赋值的类型来化分)

	如果初始化的属性的类型是自定义的对象,那么注入的时候可以通过ref 属性来引用或者直接内置bean标签注入
1 基础赋值
1)value 赋值, 直接赋值基本类型数据
	通过构造方法给属性赋值<bean id="user1"  class="org.jsoft.c_property.User"><constructor-arg  value="12" index="1"></constructor-arg><constructor-arg  value="str" index="0"></constructor-arg></bean>通过set方法给属性赋值<bean id="user2"  class="org.jsoft.c_property.User"><property name="name" value="王帅"></property>		<property name="age1111" value="12"></property></bean>
2)ref 赋值,引用对象数据
	通过构造方法给属性赋值<bean id="str"  class="java.lang.String"><constructor-arg value="王帅"></constructor-arg></bean>	<bean id="user1"  class="org.jsoft.c_property.User"><constructor-arg  value="12" index="1"></constructor-arg><constructor-arg  ref="str" index="0"></constructor-arg></bean>通过set方法给属性赋值<bean id="str"  class="java.lang.String"><constructor-arg value="王帅"></constructor-arg></bean>	<bean id="user2"  class="org.jsoft.c_property.User"><property ref="str" value="王帅"></property>		<property name="age1111" value="12"></property></bean>
3)内部Bean 赋值
		通过构造方法给属性赋值:<bean id="user1"  class="org.jsoft.c_property.User"><constructor-arg  value="12" index="1"></constructor-arg><constructor-arg  ><bean class="java.lang.String"><constructor-arg value="sss"></constructor-arg></bean></constructor-arg></bean>通过set方法给属性赋值:<bean id="user2"  class="org.jsoft.c_property.User"><!-- 【setName -》name】	 --><property name="name" ><bean class="java.lang.String"><constructor-arg value="sss"></constructor-arg></bean></property><!-- 【setAge1 -》age1】	 --><property name="age1111" value="12"></property></bean>
4)内部Bean+级联赋值

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1"><property name="personName" value="张三"></property></bean><bean class="com.hlp.demo02.User" id="user"><property name="name" value="张三"></property><property name="age" value="12"></property><property name="person" ref="person1" ></property><property name="person.personName" value="123"></property></bean>
</beans>
5)注入空值
<bean id="book3" class="run.arbor.spring5demo.Book"><property name="bname" value="Java核心技术"/><!-- 给bauthor设置空值 --><property name="bauthor"><null/></property></bean>
6)注入特殊符号

在property标签中使用value标签,并且使用CDATA的方式来注入参数,<![CDATA[参数]]>

    <bean id="book4" class="run.arbor.spring5demo.Book"><property name="bname" value="Java核心技术"/><!-- 给bauthor设置值为<凯 S. 霍斯特曼>第一种方式:把<>进行转义, &lt; 和 &gt;第二种方式:使用CDATA方式,<![CDATA[参数]]>--><property name="bauthor"><value><![CDATA[<凯 S. 霍斯特曼>]]></value></property></bean>
2 集合赋值
1)list注入

Car.java

public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

User.java

public class User {private String name;private List<String> games;private List<Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getGames() {return games;}public void setGames(List<String> games) {this.games = games;}public List<Car> getCars() {return cars;}public void setCars(List<Car> cars) {this.cars = cars;}
}

applicationContext.java

<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User"  name="user"><property name="name" value="12"></property><!-- list注入基本类型属性--><property name="games"><list><value>122</value><value>122xxx</value><value>122333ddd</value></list></property><!-- list注入引用类型属性--><property name="cars"><list><bean class="com.hlp.spring.ioc.beans.Car"></bean><bean class="com.hlp.spring.ioc.beans.Car"></bean></list></property></bean></beans>
2)arrary注入

Car.java

public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

User.java

public class User {private String name;private List<String> games;private List<Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getGames() {return games;}public void setGames(List<String> games) {this.games = games;}public List<Car> getCars() {return cars;}public void setCars(List<Car> cars) {this.cars = cars;}
}

applicationContext.java

<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User"  name="user"><property name="name" value="12"></property><!-- array注入基本类型属性--><property name="games"><array><value>122</value><value>122xxx</value><value>122333ddd</value></array></property><!-- array注入引用类型属性--><property name="cars"><array><bean class="com.hlp.spring.ioc.beans.Car"></bean><bean class="com.hlp.spring.ioc.beans.Car"></bean></array></property></bean></beans>
3)map注入

Car.java

public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

User.java

public class User {private String name;private Map<String,String> games;private Map<String,Car> cars;public String getName() {return name;}public void setName(String name) {this.name = name;}public Map<String, String> getGames() {return games;}public void setGames(Map<String, String> games) {this.games = games;}public Map<String, Car> getCars() {return cars;}public void setCars(Map<String, Car> cars) {this.cars = cars;}
}

applicationContext.java

<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car"></bean><bean class="com.hlp.spring.ioc.beans.User"  name="user"><property name="name" value="12"></property><!-- array注入基本类型属性--><property name="games"><map><entry key="a1" value="111"></entry><entry key="a2" value="111"></entry><entry key="a3" value="111"></entry></map></property><!-- array注入引用类型属性--><property name="cars"><map><entry key="a1" value-ref="car"></entry><entry key="a2" value-ref="car"></entry><entry key="a3" value-ref="car"></entry></map></property></bean></beans>

测试

    public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
4)propertis赋值

User.java


public class User {private String name;private Properties properties;public String getName() {return name;}public void setName(String name) {this.name = name;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}
}

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.hlp.spring.ioc.beans.User"  name="user"><property name="name" value="123"></property><property name="properties"><props><prop key="aaa" > 121212</prop><prop key="aaa2" > aaa</prop><prop key="aaa3" > bb</prop></props></property></bean></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user.getProperties());}
}
4)构建集合赋值

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1"><property name="personName" value="person1"></property></bean><bean class="com.hlp.demo02.Person" id="person2"><property name="personName" value="person2"></property></bean><bean class="com.hlp.demo02.Person" id="person3"><property name="personName" value="person3"></property></bean><util:list id="personList"><ref bean="person1"/><ref bean="person2"/><ref bean="person3"/></util:list><bean class="com.hlp.demo02.User"  id="user"><property name="name" value="ssss" ></property><property name="personList" ref="personList"></property></bean></beans>

Person.java

public class Person {private String personName;public String getPersonName() {return personName;}public void setPersonName(String personName) {this.personName = personName;}
}

User .java

public class User {private String name;private int age;private List<Person> personList;set、get。。
}

App .java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());}
}
4 案例
案例1:ref引用对象

HelloDao.java

public class HelloDao {public  User  serach() {return new User();}
}

HelloService .java

public class HelloService {private HelloDao helloDao;public void setHelloDao(HelloDao helloDao) {this.helloDao = helloDao;}public User search() {return helloDao.serach();}
}

HelloController.java

public class HelloController {private HelloService  helloService;public void setHelloService(HelloService helloService) {this.helloService = helloService;}public User execute() {return helloService.search();}
}

applicationContext.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- ## 案例:模拟aciton / service / dao --><bean id="helloDao"  class="org.jsoft.c_property.HelloDao"></bean><bean id="helloService" class="org.jsoft.c_property.HelloService"><property name="helloDao" ref="helloDao"></property></bean><bean id="helloAction"  class="org.jsoft.c_property.HelloController"><property name="helloService" ref="helloService"></property></bean><!-- ## 案例2(内部Bean):模拟aciton / service / dao --><bean id="helloAction2"  class="org.jsoft.c_property.HelloController"><property name="helloService"><bean class="org.jsoft.c_property.HelloService"><property name="helloDao"><bean class="org.jsoft.c_property.HelloDao"></bean></property></bean></property></bean></beans>

App.java

public class App {public static void main(String[] args) {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");//获取对象HelloController  helloAction=(HelloController) ac.getBean("helloAction2");User user = helloAction.execute();System.out.println(user);}}

在这里插入图片描述

案例2:内部Bean创建对象

HelloDao.java

public class HelloDao {public  User  serach() {return new User();}
}

HelloService .java

public class HelloService {private HelloDao helloDao;public void setHelloDao(HelloDao helloDao) {this.helloDao = helloDao;}public User search() {return helloDao.serach();}
}

HelloController.java

public class HelloController {private HelloService  helloService;public void setHelloService(HelloService helloService) {this.helloService = helloService;}public User execute() {return helloService.search();}
}

applicationContext.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- ## 案例2(内部Bean):模拟aciton / service / dao --><bean id="helloAction2"  class="org.jsoft.c_property.HelloController"><property name="helloService"><bean class="org.jsoft.c_property.HelloService"><property name="helloDao"><bean class="org.jsoft.c_property.HelloDao"></bean></property></bean></property></bean></beans>

App.java

public class App {public static void main(String[] args) {//加载配置文件,创建Bean工程ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/c_property/applicationContext.xml");//获取对象HelloController  helloAction=(HelloController) ac.getBean("helloAction2");User user = helloAction.execute();System.out.println(user);}}

在这里插入图片描述

案例3:构造注入使用ref注入对象

Car.java


public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

User.java

public class User {private String name;private Car car;public User(String name, Car car) {this.name = name;this.car = car;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}
}

applicationContext.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><bean class="com.hlp.spring.ioc.beans.Car"  id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" ><constructor-arg name="name" value="123"></constructor-arg><constructor-arg name="car" ref="car123"></constructor-arg></bean><!-- 构造注入使用c标签注入对象--><!-- 构造注入使用内部bean注入对象--><!-- 设值注入:方式二 --></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
}
案例4:构造注入使用c标签注入对象
<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><!-- 构造注入使用c标签注入对象--><bean class="com.hlp.spring.ioc.beans.Car"  id="car123" p:id="xxx" p:age="12" p:name="宝马xxx"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user"  c:name="123" c:car-ref="car123"> </bean><!-- 构造注入使用内部bean注入对象--><!-- 设值注入:方式二 --></beans>
案例5:构造注入使用内部Bena注入对象
<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 构造注入使用ref注入对象--><!-- 构造注入使用c标签注入对象--><!-- 构造注入使用内部bean注入对象--><bean class="com.hlp.spring.ioc.beans.User" id="user" ><constructor-arg name="name" value="12"></constructor-arg><constructor-arg name="car"><bean class="com.hlp.spring.ioc.beans.Car"></bean></constructor-arg></bean></beans>
案例6:属性注入使用ref注入对象

Car.java


public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

User.java

public class User {private String name;private Car car;public String getName() {return name;}public void setName(String name) {this.name = name;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}
}

applicationContext.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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" ><property name="name" value="123"></property><property name="car" ref="car"></property></bean><!-- 属性注入使用c标签注入对象--><!-- 属性注入使用内部bean注入对象--></beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");System.out.println(user);}
}
5)属性注入使用p标签注入对象
<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><!-- 属性注入使用c标签注入对象--><bean class="com.hlp.spring.ioc.beans.Car" name="car"></bean><bean class="com.hlp.spring.ioc.beans.User" id="user" p:name="123" p:car-ref="car"> </bean><!-- 属性注入使用内部bean注入对象--></beans>
6)属性注入使用内部Bena注入对象
<?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:c="http://www.springframework.org/schema/c"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 属性注入使用ref注入对象--><!-- 属性注入使用c标签注入对象--><!-- 属性注入使用内部bean注入对象--><bean class="com.hlp.spring.ioc.beans.User" ><property name="name" value="12"></property><property name="car"><bean class="com.hlp.spring.ioc.beans.Car"></bean></property></bean></beans>

4.4 自动装配

autowire:自动装配属性byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入default:默认值,不自动装配
1)autowire=“byName”

按属性名称自动装配。 Spring寻找与需要自动装配的属性同名的bean。
例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(…)方法),那么Spring将查找一个名为master的bean定义并使用它来设置该属性。

<bean id="book" class="com.dhy.Factory.Book"><property name="name"><value>时间简史</value></property><property name="money" value="50"/>
</bean><bean id="Obj" class="com.dhy.Factory.Obj" autowire="byName">

在这里插入图片描述

>>>>>> 案例

Person.java


public class Person {private String personName;set/get}

User .java

public class User {private String name;private int age;private Person person123;set/get
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"><property name="personName" value="123"></property></bean><!-- autowire="byName"。自动给person123属性赋值--><bean class="com.hlp.demo02.User" id="user" autowire="byName"><property name="name" value="12333"></property><property name="age" value="12"></property><!-- <property name="person123" ref="person123"></property>   --></bean>
</beans>

App.java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getPerson123().getPersonName());}
}

在这里插入图片描述

2)autowire=“byType”

如果容器中恰好存在一个属性类型的bean,则使该属性自动装配。
如果存在多个,则将引发致命异常,这表明您可能无法对该bean使用byType自动装配。如果没有匹配的bean,则什么都不会发生(未设置该属性)。

以属性的类型,即Book.class,作为作为查找依据,去容器中找到这个组件

 <bean id="Obj" class="com.dhy.Factory.Obj" autowire="byType">

在这里插入图片描述

>>>>>> 案例

Person.java


public class Person {private String personName;set/get}

User .java

public class User {private String name;private int age;private Person person;set/get...
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"><property name="personName" value="123"></property></bean><!-- autowire="byName"。自动给person123属性赋值--><bean class="com.hlp.demo02.User" id="user" autowire="byType"><property name="name" value="12333"></property><property name="age" value="12"></property><!-- <property name="person123" ref="person123"></property>   --></bean>
</beans>

App.java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");User user=ac.getBean("user",User.class);System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getPerson().getPersonName());}
}

在这里插入图片描述

3)自动装配全局配置

也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”

<?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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">   根据名称自动装配(全局)<!-- ###############自动装配############### -->  <bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>	<bean id="userService" class="cn.itcast.d_auto.UserService"></bean><bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean></beans>  

5 Bean的作用域

scope:指定对象的作用范围singleton:默认值,单例的,spring加载配置文件的时候,就会创建对象prototype:多例的,调用getbean方法时候创建request:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中globalsession:WEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 session
1)单例

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1" scope="singleton"><property name="personName" value="person1"></property></bean></beans>

App.java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Person bean1 = ac.getBean(Person.class);Person bean2 = ac.getBean(Person.class);System.out.println("bean1"+bean1);System.out.println("bean2"+bean2);}
}

在这里插入图片描述

2)多例

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person1" scope="prototype"><property name="personName" value="person1"></property></bean></beans>

App.java

public class App {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Person bean1 = ac.getBean(Person.class);Person bean2 = ac.getBean(Person.class);System.out.println("bean1"+bean1);System.out.println("bean2"+bean2);}
}

在这里插入图片描述

6 Bean的生命周期

<bean id="user"  class="org.jsoft.a_hello.User"  init-method="user_init"   destroy-method="user_destoty" ></bean>init-method="init_user"     对应对象的init_user方法,在对象创建爱之后执行destroy-method="xxx"  在调用容器对象的destriy方法时候执行,(只有容器用实现类,才能调用容器的销毁方法)
>>>>>> 案例

applicationContext.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user"  class="org.jsoft.a_hello.User"  init-method="user_init"   destroy-method="user_destoty" ></bean></beans>

User.java

public class User {private String name;private int age;public User() {super();System.out.println("对象创建完毕");}public void user_init() {System.out.println("创建对象之后,初始化");}public void user_destoty(){System.out.println("IOC容器销毁,调用");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

App.java


public class App_bean {@Testpublic void testIOC() {//加载配置文件,创建Bean工程//ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");//加载配置文件,创建Bean工程【用容器对象的实现类,因为要调用容器的销毁方法】ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/a_hello/applicationContext.xml");System.out.println("---IOC容器初始化完毕---");//获取对象User u=(User) ac.getBean("user");System.out.println(u);//销毁IOC容器ac.destroy();}
}

在这里插入图片描述

7 applicationContext总分配置文件

总分配置文件配置

>>>>>> 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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><import resource="resource/bean-base.xml"/><import resource="resource/bean-dao.xml"/><import resource="resource/bean-service.xml"/><import resource="resource/bean-controller.xml"/></beans>
>>>>>> resource/bean-base.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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 1) 连接池对象实例 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="user" value="root"></property><property name="password" value="root"></property><property name="initialPoolSize" value="3"></property><property name="maxPoolSize" value="6"></property><property name="maxIdleTime" value="1000"></property></bean><!-- 2) SessionFactory对象实例 --><!-- ### >>> 方式 3所有的配置全部都在Spring配置文件中完成 --><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><!-- ## 注入连接池对象 --><property name="dataSource" ref="dataSource"></property><!-- ## hibernate常用配置 --><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property><!-- hibernate映射配置 <property name="mappingLocations"><list><value>classpath:cn/itcast/entity/*.hbm.xml</value></list></property>--><!-- ## hibernate映射配置 --><property name="mappingDirectoryLocations"><list><value>classpath:org/hlp/entity</value></list></property></bean><!-- 3) 事务配置 --><!-- ## a.配置事务管理器 --><bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"></property></bean><!-- ## b.配置事务增强 --><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="get*"  read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*" read-only="false"/></tx:attributes></tx:advice><!-- ## c.配置Aop --><aop:config ><!-- 定义切入点表达式 --><aop:pointcut expression="execution(* org.hlp.dao.*.*(..))" id="pt"/><!-- 相当于aop:acpect中定义的环绕通知 --><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config><bean id="adminDao" class="org.hlp.dao.AdminDao"><property name="sf" ref="sessionFactory"></property></bean></beans>
>>>>>> resource/bean-dao.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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="adminDao" class="org.hlp.dao.AdminDao"><property name="sf" ref="sessionFactory"></property></bean><bean id="deptDao" class="org.hlp.dao.DeptDao"><property name="sf" ref="sessionFactory"></property></bean><bean id="empDao" class="org.hlp.dao.EmpDao"><property name="sf" ref="sessionFactory"></property></bean></beans>
>>>>>> resource/bean-service.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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:dwr="http://directwebremoting.org/schema/spring-dwr/spring-dwr-2.4.xsd"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="adminService" class="org.hlp.service.impl.AdminService"><property name="adminDao" ref="adminDao"></property></bean><bean id="empService" class="org.hlp.service.impl.EmpService"><property name="empDao" ref="empDao"></property></bean><bean id="deptService" class="org.hlp.service.impl.DeptService"><property name="deptDao" ref="deptDao"></property></bean></beans>

三、基于XML配置方式+注解方式的实现

3.1 基础实现

1)添加AOP依赖支持
	在使用xml方式时,核心包只需要使用core、beans、context、jar。基于注解的方式需要用到AOP的支持,所以我们需要添加AOP的依赖。

在这里插入图片描述

2)添加扫描

通过context标签component-scan属性指定扫描路径

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan>
</beans>
3)使用@Component注解

Car.java


@Component
public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
4)测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);}
}

3.2 context:component-scan标签,开启注解扫描

context:component-scan标签,配置扫描路径。

		1、使用步骤1)先引入context名称空间xmlns:context="http://www.springframework.org/schema/context"2)开启注解扫描<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>3)使用注解通过注解的方式,把对象加入ioc容器。2、使用1)使用context:component-scan标签可以指定一个或多个容器扫描路径。2)使用context:component-scan标签可以指定扫描哪些对象。
1)使用context:component-scan标签指定多个容器扫描路径

方式一:使用多个context:component-scan标签指定多个配置包

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-----><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan><context:component-scan base-package="com.hlp.spring.ioc.beans2"></context:component-scan></beans>

方式二:使用一个context:component-scan标签指定多个配置包

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-----><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><context:component-scan base-package="com.hlp.spring.ioc.beans,com.hlp2"></context:component-scan></beans>
2)使用context:component-scan标签配置注解生效

使用context:component-scan开启注解扫描。配置只扫描哪个注解。

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 添加扫描路径--><!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类--><!--不使用@Component、@Controller、@Service、@Repository注解。--><context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="false"></context:component-scan><!--不使用@Component、@Controller、@Service、@Repository注解。仅使用@Component--><context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/></context:component-scan></beans>

使用context:component-scan开启注解扫描。配置不扫描哪个注解。

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!--使用@Component、@Controller、@Service、@Repository注解。默认值。--><context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="true"></context:component-scan><!--使用@Component、@Controller、@Service、@Repository注解。@Controller注解除外--><context:component-scan base-package="com.hlp.spring.ioc.beans"  use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan></beans>

3.3 @Component、@Controller、@Service、@Repository注解

1、使用@Component、@Controller、@Service、@Repository标注类,用于注册IOC容器。注解后可以被spring框架所扫描并注入到spring容器来进行管理		【相当于spring配置文件中的bean标签。】2、使用方式:标注类时,默认bean的名称为标注类的‘首字母小写形式’。同时也可以指定bean的名称。1)bean的名称为car。		@Componentpublic class Car {...}2)bean的名称为car111。		@Component("car111"public class Car {...}
1)区别
1、@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。	2、@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。		3、@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。4、@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能,当你的一个类被@Component所注解,那么就意味着同样可以用@Repository, @Service, @Controller来替代它,同时这些注解会具备有更多的功能,而且功能各异。

在这里插入图片描述

2)使用
>>>>>> 默认bean的名称类名首字母小写

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>

Car.java


@Component
public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);}
}
>>>>>> 指定bean的名称

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>

Car.java


@Component"car123"public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car123");System.out.println(car);}
}

3.4 @Resource注解和@Autowire

在注解的场景下依赖注入我们可以通过 @Resource和@Autowired实现.
他们的区别是@Resource默认是根据name属性来查找的,
而@Autowired注解默认是根据类型査找的,@Autowired需要和@Qualifier配合实现基于name的查找

@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。

@Resource 注解和 @Autowired 注解都是在 Spring Framework 中进行依赖注入的注解,但它们之间有一些区别:1. 来源不同:@Autowired属于Spring的;@ResourceJSR-250标准的注释,属于J2EE的。@Resource 注解是由 Java EE 提供的注解,它定义在 javax.annotation.Resource 包下。@Autowired 注解是由 Spring 提供的注解,它定义在 org.springframework.beans.factory.annotation.Autowired 包下。2. 依赖注入策略不同:@Autowired默认按类型装配。@Resource默认按照名称进行装配。@Resource 注解默认按照名称进行依赖注入,如果有多个具有相同类型的依赖,可以使用 name 属性指定依赖的名称。@Autowired 注解默认按照类型进行依赖注入,如果有多个具有相同类型的依赖,可以使用 @Qualifier 注解或者 @Primary 注解指定依赖的名称或主要依赖。3. 注解属性不同:	@Resource 注解可以添加 name 属性来指定依赖的名称,还可以添加 mappedName 属性来指定依赖的 JNDI 名称。@Autowired 注解可以添加 required 属性来指定依赖是否必须,默认为 true

3.4.1 @Resource

@Resource注解:1@ResourceJava EE 的注解之一,它用于进行依赖注入。2@Resource 注解可以应用于字段、方法上。		 >>>  @Resource标注成员变量,查找IOC容器(默认根据变量名称),给变量赋值。		 							>>>  @Resource标注方法,查找IOC容器(默认根据方法参数名),给方法的参数赋值。【标注的方法只能有一个参数,否则报错】3、使用方式	 1)不写name属性: @Resourcea、默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。b、当注解写在字段上时,默认取字段名进行按照名称查找。							c、如果注解写在xxx方法上,默认取参数的名称进行装配。【xxx方式仅支持一个参数,否则报错】2)写name属性: @Resource(name="xxxx")    指定名称,仅能按照byName的方式进行匹配注入。如果找不到,则报错。
3.4.1.1 使用详解
1@Resource标注在成员变量上@Resource标注在成员变量上:默认查询IOC容器中name或id为"person123"的对象,如果有,则注入。如果没有,则按照类型查找。@Resourceprivate Person person123;@Resource(name="personz")标注在成员变量上:查询IOC容器中name或id为"personz"的对象,如果有,则注入。如果没有,则报错。@Resource(name="personz")private Person person;
3@Resource标注在方法:@Resource标注在方法:查询IOC容器中name或id为"personX1"的对象,如果有,则注入。如果没有,则根据类型查找。@Resourcepublic void  m1(Person personX1){}@Resource(name="personz")标注在方法:查询IOC容器中name或id为"personz"的对象,如果有,则注入。如果没有,则报错。@Resource(name="personz")public void  m1(Person person){}
1)@Resource 默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java

@Component
public class MySomeService {@Resourceprivate Person person;public void print(){System.out.println(person);}
}

测试

@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}

在这里插入图片描述

2)@Resource(name=“xxxx”) 指定名称,则只能根据名称查找。找不到,则会报错。

User.java


@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

ServiceImpl.java

@Component
public class ServiceImpl {@Resource(name="abc123")private  User user;public User getUser() {return user;}
}

测试

@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}

在这里插入图片描述

3.4.1.2 案例
>>>>>> @Resource标注成员变量

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java


@Component
public class MySomeService {@Resourceprivate Person person123;public void print(){System.out.println(person);}
}

App .java


@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource标注方法

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java


@Component
public class MySomeService {private Person person123;@Resource	public  void  xxx(Person person123){this.person123=person123;}public void print(){System.out.println(person);}
}

App .java


@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource(name = “person123”)标注成员变量

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java


@Component
public class MySomeService {@Resource(name = "person123")private Person person;public void print(){System.out.println(person);}
}

App .java


@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}
>>>>>> @Resource(name = “person123”)标注方法

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean class="com.hlp.demo02.Person" id="person123"></bean><context:component-scan base-package="com.hlp.demo02"></context:component-scan>
</beans>

MySomeService.java


@Component
public class MySomeService {private Person person123;@Resource(name = "person123")public  void  xxx(Person person123){this.person123=person123;}public void print(){System.out.println(person);}
}

App .java


@Component
public class App {public static void main(String[] args) {ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");MySomeService someService = ac.getBean(MySomeService.class);someService.print();;}
}

3.4.2 @Autowired

@Autowired注解:1、spring提供注解。注入时,默认根据bean的类型查找。同时也可以指定名称查找。2@Autowired 注解可以应用于标注在成员变量、构造方法、普通方法上。		 
		3、使用1@Autowired:按照类型查找@Autowired 标注成员变量:查找IOC容器【与变量同类型的对象】,并注入	@Autowiredprivate Person person;@Autowired 标注构造方法:查找IOC容器【与构造方法的参数同类型的对象】,并注入	@Autowiredpublic MySomeService(Person person2){this.person=person2;} 			@Autowired 标注方法:查找IOC容器【与方法的参数同类型的对象】,并注入											   @Autowiredpublic void ser(Person person123){this.person=person123;}注意:方法可以无参。IOC初始化后也会调用该方法。类似于init-method@Autowiredpublic void ser(){system.out.print("123")}1@Autowired配合@Qualifier("xxx")。按照指定名称查找@Autowired+@Qualifier("person123")标注成员变量:根据指定名称查找IOC容器中对象,并注入	@Autowired@Qualifier("person123")private Person person123;@Autowired+@Qualifier("person123")标注方法:查找IOC容器中同类型的对象,并注入	@Autowired@Qualifier("person123")public void ser(Person person123){this.person=person123;}@Autowired+@Qualifier("person123")不能标注构造方法
1)@Autowired 默认根据类型查找。

User.java


@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

ServiceImpl.java

@Component
public class ServiceImpl {@Autowiredprivate  User user;public User getUser() {return user;}
}

测试

@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}

在这里插入图片描述

2)@Autowired + @@Qualifier(name=“xxx”) 根据名称查找

User.java


@Component("abc123")
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

ServiceImpl.java

@Component
public class ServiceImpl {@Autowired@Qualifier("abc123")private  User user;public User getUser() {return user;}
}

测试

@Component
@ComponentScan
public class AppStart {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppStart.class);ServiceImpl serviceImpl = (ServiceImpl)ac.getBean("serviceImpl");System.out.println(serviceImpl.getUser());}
}

四、基于JavaConfig配置类方式的实现

	在Spring3.x之后开始支持]ava配置类的形式,从而舍弃配置文件的方式。

4.1 基本实现

	Java配置文件需要通过@Configuration注解标注,需要加载的实例需要通过@Bean注解标注
1)MyConfig.java 配置类
@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User user(){return  new User();}
}
2)Car.java

@Component
public class Car {private String id;private  String name;private int  age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
3)User.java
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
4)测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);User user = (User)ac.getBean("user");System.out.println(user);}
}

4.2 AnnotationConfigApplicationContext容器

AnnotationConfigApplicationContext作用:加载配置类,创建IOC容器。
 	    1、指定配置类,创建IOC容器1)使用AnnotationConfigApplicationContext创建IOC容器,指定配置类。2)配置类必须被@Configuration@Comonent@Controller等价注解所标注。配置类的作用相当于applicatonContext.xml配置文件3)基础用法a、指定一个或多个配置类,创建IOC容器ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class,MyConfig2.class);c、指定一个或多个扫描路径,创建IOC容器ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc");ApplicationContext ac=new AnnotationConfigApplicationContext("com.hlp.spring.ioc","com.hlp.spring.ioc2");2、不指定配置类,创建IOC容器。【手动注册配置类】//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();
1)指定配置类,注册IOC容器

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);}
}
2)不指定配置类,注册IOC容器。手动注册配置类
public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();Object dev = ac.getBean("dev");System.out.println(dev);}
}

4.3 @Configuration Java配置类

1、使用@Configuration的作用:配置java配置类。相当于spring配置文件。2、@Configuration与@Compoonent、@Controller、@Service、@Repository注解等价。

案例

@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User user(){return  new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);Car car = (Car)ac.getBean("car");System.out.println(car);User user = (User)ac.getBean("user");System.out.println(user);}
}

4.4 @ComponentScan、@ComponentScans注解,配置扫描包

1@ComponentScan@ComponentScans作用:1)在基于java配置类的方式中,一般结合@Configuration使用,实现IOC容器。	        2)用于配置扫描路径。相当于applicationContext.xml中的context:component-scan标签。	
2、@ComponentScan指定扫描路径,可以指定包名,也可以指定xxx.class类文件指定包名:扫描当前包下的文件以及子包文件,创建Bean。指定类文件:扫描当前类所在包的文件及其子包文件,创建Bean。1)默认扫描当前标注类所在包及其子包的类。@ComponentScan2)指定一个扫描路径@ComponentScan("com.hlp.spring.ioc.beans")@ComponentScan({"com.hlp.spring.ioc.beans"})@ComponentScan(basePackages = "com.hlp.spring.ioc.beans")@ComponentScan(basePackages = {"com.hlp.spring.ioc.beans"})3)指定多个扫描路径@ComponentScan({"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})@ComponentScan(basePackages = {"com.hlp.spring.ioc.beans","com.hlp.spring.ioc.beans"})4)指定一个或多个类文件@ComponentScan(basePackageClasses={Car.class})@ComponentScan(basePackageClasses={Car.class,User.class})3、@ComponentScan其他属性@Configuration@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=false,includeFilters ={@ComponentScan.Filter(Controller.class)} )public class MyConfig {@Bean("myUser")public User myUser(){return  new User();}}
4、使用@ComponentScans指定扫描路径,作用与@ComponentScan等价
1)使用@ComponentScan指定扫描路径

MyConfig.java

@Configuration
@ComponentScan("com.hlp.spring.ioc.beans")
public class MyConfig {@Bean("myUser")public User myUser(){return  new User();}
}

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2)使用@ComponentScans指定扫描路径

MyConfig.java

@Configuration
@ComponentScans({@ComponentScan({"com.hlp.spring.ioc"}),@ComponentScan({"com.hlp.spring.ioc.beans"})
}) public class MyConfig {@Bean("myUser")public User myUser(){return  new User();}
}

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
3)属性示例

MyConfig.java

@Configuration
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=false,includeFilters ={@ComponentScan.Filter(Controller.class)} )
@ComponentScan(basePackages = "com.hlp.spring.ioc.beans",useDefaultFilters=true,excludeFilters ={@ComponentScan.Filter(Controller.class)} )
public class MyConfig {@Bean("myUser")public User myUser(){return  new User();}
}

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}

4.5 @Bean注解

	@Bean1、相当于applicationContext中的bean标签。2、一般在@Configuration标注的类中使用。由于@Configuration与其他@Component等标签等价,所以也可以在@Component等标签中标注的类中使用。3、默认注册的bean的名称为标注的方法名。同时也可以指定bean的名称默认注册bean的名称为方法名myUser@Beanpublic User myUser(){return  new User();}指定bean的名称为abc123@Bean("abc123")public User myUser(){return  new User();}4、@Bean标注的方法有参数,会自动注入参数对象。1)@Bean标注的方法可以有多个参数。spring默认会根据参数类型查找IOC容器注入参数。如果找不到,就报错。2)@Bean标注的方法可以有多个参数。通过@Qualifier("name")注解标注参数,spring会根据名称查找IOC容器注入参数。如果找不到,就报错。
1) 默认注册的bean的名称为标注的方法名
@Configuration
@ComponentScan
public class MyConfig {@Beanpublic User myUser(){return  new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
//        Car car = (Car)ac.getBean("car");
//        System.out.println(car);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2) 指定bean的名称
@Configuration
@ComponentScan
public class MyConfig {@Bean("abc123")public User myUser(){return  new User();}
}
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
//        Car car = (Car)ac.getBean("car");
//        System.out.println(car);User user = (User)ac.getBean("abc123");System.out.println(user);}
}
3) @Bean标注有多个参数方法,默认会根据参数类型查找IOC并将对象注入到参数中

DataSourceConfig.java

@Component("abc")
public class DataSourceConfig {@Beanpublic DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Beanpublic JdbcTemplate testBean(DataSource aa, DataSource a3){System.out.println(aa);System.out.println(a3);return null;}}

App.java

@Component
@ComponentScan
public class App {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);}
}

在这里插入图片描述

4) @Bean标注有多个参数方法,通过(@Qualifier(“springDS2”)标注参数,会根据名称查找IOC并将对象注入到参数中

DataSourceConfig.java

@Component("abc")
public class DataSourceConfig {@Bean("db1")public DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Bean("db2")public DataSource dataSource(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setUrl("jdbc:mysql://localhost:3306/demo");return dataSource;}@Beanpublic JdbcTemplate testBean((@Qualifier("db1")DataSource aa){System.out.println(aa);return null;}}

App.java

@Component
@ComponentScan
public class App {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);}
}

4.6 @Conditional、@Profile条件注解

1 @Conditional
	@Conditional注解:配置@Bean注解使用,决定是否将注册的Bean注入到IOC容器中1、使用步骤1)编写一个类MyConditional,实现Condition接口中的matches方法。2)使用@Conditional(MyConditional.class)进行标注注册的bean。3)如果MyConditional实现的matches返回true,则注入标注bean,如果为false,则不注入标注bean。2、使用方式1)指定一个条件//如果MyConditional中的matches方法返回true,则注入。否则不注入。@Conditional(MyConditional.class)//如果MyConditional中的matches方法返回true,则注入。否则不注入。@Conditional({MyConditional.class})								2)指定两个条件//如果MyConditional和MyConditional2中的matches方法都返回true,则注入。否则不注入。@Conditional({MyConditional.class,MyConditional2.class})
1)自定义MYConditional类,实现Condition接口。

该方法返回true,则允许注册标注bean。否则不允许注册标注bean。

public class MYConditional implements Condition {//matches方法逻辑:加载“com.hlp.spring.ioc.User”类。如果为空,则返回false。如果不为空,则返回true@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {ClassLoader classLoader = conditionContext.getClassLoader();try {Class<?> clazz = classLoader.loadClass("com.hlp.spring.ioc.User");if(clazz!=null){return true;}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}return false;}
}
2)配置使用条件
@Configuration
@ComponentScan
public class MyConfig {@Bean("myUser")@Conditional({MYConditional.class})public User myUser(){return  new User();}
}
3)测试
public class AppStart {public static void main(String[] args) {ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);User user = (User)ac.getBean("myUser");System.out.println(user);}
}
2 @Profile 注解
@Profile 注解:1、@Profile注解继承了@Conditional条件注解,同时指定了条件类。@Conditional({ProfileCondition.class})2、条件类ProfileCondition.class是Spring提供的,内置的条件类。其作用是读取Environment中的activeProfile属性设置的值。与@Profile指定的值进行比较。如果相同,则注入该bean。如果不同,则不注入。
1)作用

@Profile使用时,指定value值。
在这里插入图片描述

@Profile注解源码:
该注解继承了@Conditional注解。@Conditional注解中也指定了条件类ProfileCondition.class
在这里插入图片描述ProfileCondition源码
该条件类的作用是:读取环境变量中的activeProfile属性,与当前@Profile指定值比较,如果相同,则返回true,即允许注入。否则不允许注入。
在这里插入图片描述

2)使用案例

Datasource.java


public class Datasource {private String url;private String password;private String name;public Datasource(String url, String password, String name) {this.url = url;this.password = password;this.name = name;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Datasource{" +"url='" + url + '\'' +", password='" + password + '\'' +", name='" + name + '\'' +'}';}
}

MyConfig.java


@Configuration
public class MyConfig {//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与“dev”相同,则注入该bean。@Bean("ds")@Profile("dev")public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}//@Profile("dev"):读取环境变量中activeProfile属性,如果属性值与“pro”相同,则注入该bean。@Bean("ds")@Profile("pro")public Datasource  datasource2(){return  new Datasource("jdbc:mysql://127.0.0.1/pro","123333","12333");}
}

测试
指定环境变量属性为pro。那么 @Profile(“pro”)标注的,则生效。

public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();//设置对应的环境信息ac.getEnvironment().setActiveProfiles("pro");//手动注册配置类【注册后必须刷新】ac.register(MyConfig.class);ac.refresh();Object dev = ac.getBean("ds");System.out.println(dev);}
}

在这里插入图片描述

4.7 Bean的作用域

1、通过bean标签或通过@Bean注解注入的bean,默认情况下均为单例模式。即多次调用getBean(),获取的对象都是同一个对象。可通过scope进行设置。	2、scope用于设置bean的作用域。scope="singleton"  单例模式,默认值。scope="prototype"  原型模式。
		3、bean标签作用域设置:1)使用spring配置文件配置bean。默认为单例。<bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>2)基础设置设置单例模式,可省略,默认值。<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>设置多例模式<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
4@Bean注解作用域设置:1)使用@Bean配置bean。默认为单例。@Bean("ds" )public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}2)基础设置设置单例模式方式一@Bean("ds" )@Scopepublic Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}方式二@Bean("ds" )@Scope("singleton")public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}设置多例模式@Bean("ds" )@Scope("prototype")public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}

1 基于xml配置,作用域详解

1)默认情况下为单例模式

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
</beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}

在这里插入图片描述

2)通过scope属性设置单例作用域(默认,可省略)

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>
</beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}

在这里插入图片描述

3)通过scope属性设置多例作用域

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
</beans>

测试

public class AppStart {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car = (Car)ac.getBean("car");System.out.println(car);Car car2 = (Car)ac.getBean("car");System.out.println(car2);}
}

在这里插入图片描述

2 基于JavaConfig配置,作用域详解

1)默认情况下为单例模式

MyConfig.java

@Configuration
public class MyConfig {@Bean("ds" )public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}

测试


public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}

在这里插入图片描述

2)通过scope设置单例作用域(默认,可省略)

MyConfig.java

@Configuration
public class MyConfig {@Bean("ds" )@Scope("singletone")public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}

测试


public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}

在这里插入图片描述

3)通过scope属性设置多例作用域

MyConfig.java

@Configuration
@Configuration
public class MyConfig {@Bean("ds" )@Scope("prototype")public Datasource  datasource1(){return  new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");}}

测试


public class App {public static void main(String[] args) {//创建无配置类的IOC容器AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);Object dev = ac.getBean("ds");System.out.println(dev);Object dev2 = ac.getBean("ds");System.out.println(dev2);}
}

在这里插入图片描述

Spring框架提供了一系列的生命周期注解,用于管理bean对象的创建、初始化和销毁过程。下面是对一些常用的生命周期注解进行详解:@PostConstruct:该注解被标注在方法上,表示在对象创建完成并且属性注入完成后执行。通常用于执行一些初始化操作。@PreDestroy:该注解也被标注在方法上,表示在对象销毁之前执行。通常用于执行一些资源释放的操作。@Autowired:该注解用于自动注入依赖对象。当容器中存在多个相同类型的bean时,可以结合@Qualifier注解指定具体的bean。@Qualifier:该注解与@Autowired注解结合使用,用于指定注入的具体bean。可以通过指定bean的名称或者自定义的限定符来确定注入的对象。@Resource:该注解也用于自动注入依赖对象,可用于注入其他bean、属性、方法或者配置文件等。它支持根据名称进行注入,默认按照byName方式查找,如果找不到对应的bean,则按照byType方式查找。@Value:该注解用于注入属性值,可以直接注入基本类型、字符串、数组、集合以及其他bean对象等。@Component:该注解用于将类标识为一个组件,表示该类将由Spring容器进行管理,可通过扫描@ComponentScan注解指定的包路径进行自动扫描。@Controller、@Service、@Repository:这些注解分别用于标识控制层、服务层和数据访问层的组件,是@Component的特殊化,用于更细粒度地描述组件的职责。@Configuration:该注解用于标识配置类,表示该类是一个配置类,其中可能包含@Bean注解用于定义bean对象。@Bean:该注解用于标识方法,表示将方法返回的对象注册为一个bean,可以指定bean的名称、作用域、依赖关系等。

这篇关于一、Spring基础 --- 基础内容(一) (咕P4)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888887

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2