一、Spring简介
1 来源
Struts与Hibernate可以做什么事?
xml
Struts:
Mvc中控制层解决方案
可以进行请求数据自动封装、类型转换、文件上传、效验...
Hibernate:
持久层的解决方案;
可以做到,
把对象保存到数据库,
从数据库中取出的是对象。
传统的开发模式、开发流程
xml
传统的开发模式:基于mvc模式进行项目开发
java
基于mvc的项目框架结构:
Entity / dao / service / action
// 1. 实体类
class User{
}
//2. dao
class UserDao{
.. 访问db
}
//3. service
class UserService{
UserDao userDao = new UserDao();
}
//4. action
class UserAction{
UserService userService = new UserService();
..
拿到数据或结果
}
用户访问:
/user.action ----> Tomcat (服务器创建Action、Service、dao
思考
java
思考:
1. 对象创建创建能否写死?
2. 对象创建细节
对象数量
action 多个 【维护成员变量】
service 一个 【不需要维护公共变量】
dao 一个 【不需要维护公共变量】
创建时间
action 访问时候创建
service 启动时候创建
dao 启动时候创建
3. 对象的依赖关系
action 依赖 service
service依赖 dao
=======================================================
总结:
spring就是解决上面的问题的!
简单来说,就是处理对象的创建的、以及对象的依赖关系!
2 spring概念
xml
官网地址 :http://www.spring.io
1.1 作用
js
作用:简化Java开发的。Spring不仅只是一个框架,Spring已经成为了一种生态。(与其说是Java开发,不如说是Spring开发)
Spring可以做非常多的事情,但归根结底,支撑Sprine的仅仅是少许的基本理念,所有的理念都可以追溯到Sprine最根本的使命上!简化java开发。这是一个郑重的承诺。
许多框架都声称在某些方面做了简化,但Spring的目标是致力于全方位的简化java开发。这势必引出更多的解释,Spring是如何简化Java开发的?
为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
1、基于POI0的轻量级和最小侵入式编程;
2、通过控制反转和依赖注入以及面向接口实现松耦合;
3、基于切面和惯例进行声明式编程:
4、通过切面和模板减少样板式代码,
1.2 历史来源
js
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专有名词
kotlin
+++ 组件/框架设计
1)侵入式设计
引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。
例如: Struts框架(使用struts的校验功能,必须继承ActionSupport,这是一种侵入式设计)
2)非侵入式设计
引入了框架,对现有的类结构没有影响。
例如:Hibernate框架 / Spring框架
3)区别侵入式、非侵入式的要点是:
引入该框架是否要继承某个特定类。
如:引入struts框架,如果要实现校验功能,action必须要继承ActionSupport,这是侵入式设计,所以struts是侵入式框架。
引入hibernate,虽然配置了xml配置文件,但是dao无须继承什么类。所以hibernate是非侵入式设计。
kotlin
+++ 控制反转(IOC)和依赖注入(DI)
1) Inversion on Control , 控制反转 IOC
对象的创建交给外部容器完成,这个就做控制反转.
2) dependency injection
处理对象的依赖关系
区别:
控制反转, 解决对象创建的问题 【对象创建交给别人】
依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】
先有控制反转,再有依赖注入,(一个流程步骤)
kotlin
+++ AOP
面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。
切面举例:事务、日志、权限;
js
+++ 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 结构图
js
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包下载
js
官网下载教程
https://blog.csdn.net/m0_52861000/article/details/128883819
jar包下载地址(注意:没找到release库,只找到了SNAPSHOT库):
https://repo.spring.io/ui/native/snapshot/org/springframework/spring/
xml
下载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文件
xml
1) 源码, jar文件:spring-framework-3.2.5.RELEASE
commons-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)配置文件
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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="user" class="org.jsoft.a_hello.User"></bean>
</beans>
创建实体
java
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;
}
}
测试
java
public class App {
@Test
public 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());
}
@Test
public 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
<?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类
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
<?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代码实现
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
java
方式一:
Resource rs=(Resource) new ClassPathResource("org/jsoft/a_hello/applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(rs);
java
@Test
public 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
java
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");
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);
}
}
2.2 BeanFactory和ApplicationContext的区别
js
ApplicationContext、BeanFactory都是IOC容器。
ApplicationContext是BeanFactory的子接口。ApplicationContext功能肯定比BeanFactory的功能更强大。
ApplicationContext容器在初始化的时候,就会初始化Bean。
而BeanFactory容器中的Bean是懒加载,在初始化的时候,不会初始化Bean,只有在调用getBean时,才会创建对象。
2.3 容器相关方法
1)一般方法
java
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获取
xml
<bean class="com.hlp.spring.ioc.beans.Car" name="myCar"></bean>
java
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car)ac.getBean("myCar");
System.out.println(car);
}
根据id获取
xml
<bean class="com.hlp.spring.ioc.beans.Car" name="myCar" id="myCar2"></bean>
java
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car)ac.getBean("myCar");
System.out.println(car);
}
根据class文件获取
xml
<bean class="com.hlp.spring.ioc.beans.Car" ></bean>
java
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car)ac.getBean(Car.class);
System.out.println(car);
}
如果我们根据类型去容器中获取对象,如果该类型在容器中有多个实例,那么会抛出异常信息
这时,我们可以根据组合的方式去查找
组合方式查找
xml
<bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
<bean class="com.hlp.spring.ioc.beans.Car" ></bean>
java
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的实例化
xml
SpringIOC容器,是spring核心内容。
作用: 创建对象 & 处理对象的依赖关系
xml
IOC容器创建对象, 有几种方式:
1) 调用无参数构造器
2) 带参数构造器
3) 工厂创建对象
工厂类,静态方法创建对象
工厂类,非静态方法创建对象
3.1 Bean标签
xml
<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 相当于 session
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
autowire:自动装配属性
byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样
byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入
default:默认值,不自动装配
3.2 Bean的实例化
3.2.1 构造函数
xml
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静态工厂
java
public class MyBeanFactory {
public static Car getInstance1(){
return new Car();
}
}
applicationContext-static.xml 配置文件
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>
测试
java
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工厂
java
public class MyBeanFactory {
public Car getInstance1(){
return new Car();
}
}
applicationContext-static.xml 配置文件
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>
测试
java
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介绍
js
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接口
java
1、getObject()方法:
获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。
2、getObjectType()方法
获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。
3、isSingleton()方法
判断由此工厂创建的对象实例是否为单例模式。
默认情况下,FactoryBean创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。
4、FactoryBean在Spring中的作用
当配置文件中< bean>的 class 属性配置的实现类是 FactoryBean 时,通过 getBean()方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象。
相当于FactoryBean#getObject()代理了 getBean()方法。
java
public interface FactoryBean<T> {
// 获取由此工厂创建的对象实例
T getObject() throws Exception;
// 获取由此工厂创建的对象实例的类型
Class<?> getObjectType();
// 判断由此工厂创建的对象实例是否为单例模式
default boolean isSingleton() {
return true;
}
}
3)FactoryBean使用
User.java
java
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
...
}
UserFactoryBean .java
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
java
<?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.xsd
http://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
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、动态创建对象
java
public class MyFactoryBean implements FactoryBean<Object> {
@Override
public Object getObject() throws Exception {
// 根据配置或条件动态创建对象
if (someCondition) {
return new MyObject();
} else {
return new AnotherObject();
}
}
@Override
public Class<?> getObjectType() {
// 返回实际创建的对象的类型
return Object.class;
}
@Override
public boolean isSingleton() {
// 返回是否为单例对象
return true;
}
}
2、对象的装配和初始化
java
public class MyFactoryBean implements FactoryBean<MyObject> {
private String name;
private int age;
@Override
public MyObject getObject() throws Exception {
// 创建对象并进行装配和初始化
MyObject myObject = new MyObject();
myObject.setName(name);
myObject.setAge(age);
return myObject;
}
@Override
public Class<?> getObjectType() {
return MyObject.class;
}
@Override
public boolean isSingleton() {
return true;
}
// 设置属性值的方法
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
3、对象的代理和包装
java
public class MyFactoryBean implements FactoryBean<MyObject> {
private MyObject target;
@Override
public MyObject getObject() throws Exception {
// 对目标对象进行代理和包装
MyObjectProxy proxy = new MyObjectProxy(target);
return proxy.getProxy();
}
@Override
public Class<?> getObjectType() {
return MyObject.class;
}
@Override
public boolean isSingleton() {
return true;
}
// 设置目标对象的方法
public void setTarget(MyObject target) {
this.target = target;
}
}
3.3 其他注意事项
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 默认bean的名称为'com.hlp.spring.ioc.beans.Car' -->
<bean class="com.hlp.spring.ioc.beans.Car" ></bean>
</beans>
测试
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- <!– 使用name、id均可为bean命名。 –>-->
<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>
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 默认bean的名称为'com.hlp.spring.ioc.beans.Car' -->
<!-- <bean class="com.hlp.spring.ioc.beans.Car" ></bean>-->
<!-- <!– 使用name、id均可为bean命名。 –>-->
<bean class="com.hlp.spring.ioc.beans.Car" name="car1,car2,car3" ></bean>
</beans>
java
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 构造注入
java
构造注入:通过构造方法实现属性的注入。
第一步需要添加对应的有参构造方法,第二步在配置文件中添加对应的配置信息。
方式一:
<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
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
<?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>
测试
java
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
<?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>
测试
java
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
<?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>
测试
java
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
<?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>
测试
java
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赋值)
xml
通过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
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
<?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>
测试
java
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
<?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 赋值方式(根据赋值的类型来化分)
xml
如果初始化的属性的类型是自定义的对象,那么注入的时候可以通过ref 属性来引用
或者直接内置bean标签注入
1 基础赋值
1)value 赋值, 直接赋值基本类型数据
xml
通过构造方法给属性赋值
<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 赋值,引用对象数据
xml
通过构造方法给属性赋值
<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 赋值
xml
通过构造方法给属性赋值:
<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
<?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.xsd
http://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)注入空值
xml
<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[参数]]>
xml
<bean id="book4" class="run.arbor.spring5demo.Book">
<property name="bname" value="Java核心技术"/>
<!-- 给bauthor设置值为<凯 S. 霍斯特曼>
第一种方式:把<>进行转义, < 和 >
第二种方式:使用CDATA方式,<![CDATA[参数]]>
-->
<property name="bauthor">
<value><![CDATA[<凯 S. 霍斯特曼>]]></value>
</property>
</bean>
2 集合赋值
1)list注入
Car.java
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
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
<?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
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
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
<?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
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
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
<?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>
测试
java
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
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
<?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>
测试
java
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
<?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.xsd
http://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
java
public class Person {
private String personName;
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
}
User .java
java
public class User {
private String name;
private int age;
private List<Person> personList;
set、get。。
}
App .java
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
java
public class HelloDao {
public User serach() {
return new User();
}
}
HelloService .java
java
public class HelloService {
private HelloDao helloDao;
public void setHelloDao(HelloDao helloDao) {
this.helloDao = helloDao;
}
public User search() {
return helloDao.serach();
}
}
HelloController.java
java
public class HelloController {
private HelloService helloService;
public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}
public User execute() {
return helloService.search();
}
}
applicationContext.xml
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">
<!-- ## 案例:模拟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
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
java
public class HelloDao {
public User serach() {
return new User();
}
}
HelloService .java
java
public class HelloService {
private HelloDao helloDao;
public void setHelloDao(HelloDao helloDao) {
this.helloDao = helloDao;
}
public User search() {
return helloDao.serach();
}
}
HelloController.java
java
public class HelloController {
private HelloService helloService;
public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}
public User execute() {
return helloService.search();
}
}
applicationContext.xml
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">
<!-- ## 案例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
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
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
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
<?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>
测试
java
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
<?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
<?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
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
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
<?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>
测试
java
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
<?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
<?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 自动装配
java
autowire:自动装配属性
byName:根据属性名称注入,需要注入bean的id值要和类中属性的名称一样
byType:根据属性类型注入,如果同类型的bean有两个或多个则不能使用类型注入
default:默认值,不自动装配
1)autowire="byName"
按属性名称自动装配。 Spring寻找与需要自动装配的属性同名的bean。
例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(...)方法),那么Spring将查找一个名为master的bean定义并使用它来设置该属性。
xml
<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
java
public class Person {
private String personName;
set/get
}
User .java
java
public class User {
private String name;
private int age;
private Person person123;
set/get
}
applicationContext.xml
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.xsd
http://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
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,作为作为查找依据,去容器中找到这个组件
xml
<bean id="Obj" class="com.dhy.Factory.Obj" autowire="byType">
>>>>>> 案例
Person.java
java
public class Person {
private String personName;
set/get
}
User .java
java
public class User {
private String name;
private int age;
private Person person;
set/get...
}
applicationContext.xml
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.xsd
http://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
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
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" 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的作用域
java
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
<?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.xsd
http://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
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
<?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.xsd
http://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
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的生命周期
xml
<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
<?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 id="user" class="org.jsoft.a_hello.User" init-method="user_init" destroy-method="user_destoty" ></bean>
</beans>
User.java
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
java
public class App_bean {
@Test
public 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
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://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
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://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
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://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
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://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
在使用xml方式时,核心包只需要使用core、beans、context、jar。
基于注解的方式需要用到AOP的支持,所以我们需要添加AOP的依赖。
2)添加扫描
通过context标签component-scan属性指定扫描路径
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 添加扫描路径-->
<!-- 作用:ioc容器初始化时,会扫描该标签指定的路径,路径下是否有通过注解标识的java类-->
<context:component-scan base-package="com.hlp.spring.ioc.beans"></context:component-scan>
</beans>
3)使用@Component注解
Car.java
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)测试
java
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标签,配置扫描路径。
xml
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.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注解
js
1、使用@Component、@Controller、@Service、@Repository标注类,用于注册IOC容器。
注解后可以被spring框架所扫描并注入到spring容器来进行管理
【相当于spring配置文件中的bean标签。】
2、使用方式:标注类时,默认bean的名称为标注类的'首字母小写形式'。同时也可以指定bean的名称。
1)bean的名称为car。
@Component
public class Car {...}
2)bean的名称为car111。
@Component("car111")
public class Car {...}
1)区别
xml
1、@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。
2、@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。
3、@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
4、@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能,
当你的一个类被@Component所注解,
那么就意味着同样可以用@Repository, @Service, @Controller来替代它,
同时这些注解会具备有更多的功能,而且功能各异。
2)使用
>>>>>> 默认bean的名称类名首字母小写
applicationContext.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>
Car.java
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;
}
}
测试
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.hlp.spring.ioc"></context:component-scan>
</beans>
Car.java
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;
}
}
测试
java
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,都可以写在字段上,或者方法上。
java
@Resource 注解和 @Autowired 注解都是在 Spring Framework 中进行依赖注入的注解,但它们之间有一些区别:
1. 来源不同:@Autowired属于Spring的;@Resource为JSR-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
java
@Resource注解:
1、@Resource 是 Java EE 的注解之一,它用于进行依赖注入。
2、@Resource 注解可以应用于字段、方法上。
>>> @Resource标注成员变量,查找IOC容器(默认根据变量名称),给变量赋值。
>>> @Resource标注方法,查找IOC容器(默认根据方法参数名),给方法的参数赋值。
【标注的方法只能有一个参数,否则报错】
3、使用方式
1)不写name属性: @Resource
a、默认按照byName的方式进行匹配注入。如果匹配不到,再按 byType的方式进行匹配。
b、当注解写在字段上时,默认取字段名进行按照名称查找。
c、如果注解写在xxx方法上,默认取参数的名称进行装配。【xxx方式仅支持一个参数,否则报错】
2)写name属性: @Resource(name="xxxx")
指定名称,仅能按照byName的方式进行匹配注入。如果找不到,则报错。
3.4.1.1 使用详解
java
1)@Resource标注在成员变量上
@Resource标注在成员变量上:
默认查询IOC容器中name或id为"person123"的对象,
如果有,则注入。如果没有,则按照类型查找。
@Resource
private Person person123;
@Resource(name="personz")标注在成员变量上:
查询IOC容器中name或id为"personz"的对象,
如果有,则注入。如果没有,则报错。
@Resource(name="personz")
private Person person;
java
3)@Resource标注在方法:
@Resource标注在方法:
查询IOC容器中name或id为"personX1"的对象,
如果有,则注入。如果没有,则根据类型查找。
@Resource
public 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
<?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.xsd
http://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
java
@Component
public class MySomeService {
@Resource
private Person person;
public void print(){
System.out.println(person);
}
}
测试
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();;
}
}
2)@Resource(name="xxxx") 指定名称,则只能根据名称查找。找不到,则会报错。
User.java
js
@Component("abc123")
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ServiceImpl.java
java
@Component
public class ServiceImpl {
@Resource(name="abc123")
private User user;
public User getUser() {
return user;
}
}
测试
java
@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
<?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.xsd
http://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
java
@Component
public class MySomeService {
@Resource
private Person person123;
public void print(){
System.out.println(person);
}
}
App .java
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
<?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.xsd
http://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
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
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
<?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.xsd
http://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
java
@Component
public class MySomeService {
@Resource(name = "person123")
private Person person;
public void print(){
System.out.println(person);
}
}
App .java
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
<?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.xsd
http://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
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
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
java
@Autowired注解:
1、spring提供注解。注入时,默认根据bean的类型查找。同时也可以指定名称查找。
2、@Autowired 注解可以应用于标注在成员变量、构造方法、普通方法上。
java
3、使用
1)@Autowired:按照类型查找
@Autowired 标注成员变量:查找IOC容器【与变量同类型的对象】,并注入
@Autowired
private Person person;
@Autowired 标注构造方法:查找IOC容器【与构造方法的参数同类型的对象】,并注入
@Autowired
public MySomeService(Person person2){
this.person=person2;
}
@Autowired 标注方法:查找IOC容器【与方法的参数同类型的对象】,并注入
@Autowired
public void ser(Person person123){
this.person=person123;
}
注意:方法可以无参。IOC初始化后也会调用该方法。类似于init-method
@Autowired
public 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
js
@Component("abc123")
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ServiceImpl.java
java
@Component
public class ServiceImpl {
@Autowired
private User user;
public User getUser() {
return user;
}
}
测试
java
@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
js
@Component("abc123")
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ServiceImpl.java
java
@Component
public class ServiceImpl {
@Autowired
@Qualifier("abc123")
private User user;
public User getUser() {
return user;
}
}
测试
java
@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配置类方式的实现
xml
在Spring3.x之后开始支持]ava配置类的形式,从而舍弃配置文件的方式。
4.1 基本实现
xml
Java配置文件需要通过@Configuration注解标注,需要加载的实例需要通过@Bean注解标注
1)MyConfig.java 配置类
java
@Configuration
@ComponentScan
public class MyConfig {
@Bean
public User user(){
return new User();
}
}
2)Car.java
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
java
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4)测试
java
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容器
xml
AnnotationConfigApplicationContext作用:加载配置类,创建IOC容器。
java
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容器
java
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容器。手动注册配置类
java
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配置类
js
1、使用@Configuration的作用:配置java配置类。相当于spring配置文件。
2、@Configuration与@Compoonent、@Controller、@Service、@Repository注解等价。
案例
java
@Configuration
@ComponentScan
public class MyConfig {
@Bean
public User user(){
return new User();
}
}
java
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注解,配置扫描包
java
1、@ComponentScan或@ComponentScans作用:
1)在基于java配置类的方式中,一般结合@Configuration使用,实现IOC容器。
2)用于配置扫描路径。相当于applicationContext.xml中的context:component-scan标签。
js
2、@ComponentScan指定扫描路径,可以指定包名,也可以指定xxx.class类文件
指定包名:扫描当前包下的文件以及子包文件,创建Bean。
指定类文件:扫描当前类所在包的文件及其子包文件,创建Bean。
1)默认扫描当前标注类所在包及其子包的类。
@ComponentScan
2)指定一个扫描路径
@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();
}
}
js
4、使用@ComponentScans指定扫描路径,作用与@ComponentScan等价
1)使用@ComponentScan指定扫描路径
MyConfig.java
java
@Configuration
@ComponentScan("com.hlp.spring.ioc.beans")
public class MyConfig {
@Bean("myUser")
public User myUser(){
return new User();
}
}
测试
java
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
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();
}
}
测试
java
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
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();
}
}
测试
java
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注解
js
@Bean
1、相当于applicationContext中的bean标签。
2、一般在@Configuration标注的类中使用。由于@Configuration与其他@Component等标签等价,所以也可以在@Component等标签中标注的类中使用。
3、默认注册的bean的名称为标注的方法名。同时也可以指定bean的名称
默认注册bean的名称为方法名myUser
@Bean
public 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的名称为标注的方法名
java
@Configuration
@ComponentScan
public class MyConfig {
@Bean
public User myUser(){
return new User();
}
}
java
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的名称
java
@Configuration
@ComponentScan
public class MyConfig {
@Bean("abc123")
public User myUser(){
return new User();
}
}
java
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
java
@Component("abc")
public class DataSourceConfig {
@Bean
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
public JdbcTemplate testBean(DataSource aa, DataSource a3){
System.out.println(aa);
System.out.println(a3);
return null;
}
}
App.java
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
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;
}
@Bean
public JdbcTemplate testBean((@Qualifier("db1")DataSource aa){
System.out.println(aa);
return null;
}
}
App.java
java
@Component
@ComponentScan
public class App {
public static void main(String[] args) {
ApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
}
}
4.6 @Conditional、@Profile条件注解
1 @Conditional
js
@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。
java
public class MYConditional implements Condition {
//matches方法逻辑:加载"com.hlp.spring.ioc.User"类。如果为空,则返回false。如果不为空,则返回true
@Override
public 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)配置使用条件
java
@Configuration
@ComponentScan
public class MyConfig {
@Bean("myUser")
@Conditional({MYConditional.class})
public User myUser(){
return new User();
}
}
3)测试
java
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 注解
js
@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
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;
}
@Override
public String toString() {
return "Datasource{" +
"url='" + url + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
'}';
}
}
MyConfig.java
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")标注的,则生效。
java
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的作用域
js
1、通过bean标签或通过@Bean注解注入的bean,默认情况下均为单例模式。即多次调用getBean(),获取的对象都是同一个对象。可通过scope进行设置。
2、scope用于设置bean的作用域。
scope="singleton" 单例模式,默认值。
scope="prototype" 原型模式。
xml
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>
java
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" )
@Scope
public 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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean class="com.hlp.spring.ioc.beans.Car" id="car" ></bean>
</beans>
测试
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="singleton" ></bean>
</beans>
测试
java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean class="com.hlp.spring.ioc.beans.Car" id="car" scope="prototype" ></bean>
</beans>
测试
java
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
java
@Configuration
public class MyConfig {
@Bean("ds" )
public Datasource datasource1(){
return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
}
}
测试
java
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
java
@Configuration
public class MyConfig {
@Bean("ds" )
@Scope("singletone")
public Datasource datasource1(){
return new Datasource("jdbc:mysql://127.0.0.1/dev","123","123");
}
}
测试
java
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
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");
}
}
测试
java
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的名称、作用域、依赖关系等。