文章目录

  • 1. 简介
  • 2. IOC理论推导
  • 3. HelloSpring
  • 4. IOC创建对象的方式
    • 4.1 使用无参构造创建对象(默认)
    • 4.2 使用有参构造创建对象
  • 5. Spring配置
    • 5.1 别名
    • 5.2 bean的配置
    • 5.3 import标签
  • 6. 属性注入
  • 7. 自动装配
    • 7.1 测试环境搭建
    • 7.2 byName自动装配
    • 7.3 byType自动装配
    • 7.4 使用注解实现自动装配
  • 8. 使用注解开发

1. 简介

Spring就是一个轻量级的控制反转(IOC) 和面向切面编程(AOP)的框架!
Spring目的:解决企业应用开发的复杂性

2. IOC理论推导

传统new对象的逻辑开发:
dao—>daoImpl—>service—>serviceImpl

如果用户想要切换数据库实现,所有的主动权在程序员的手上,需要修改程序。

所以要控制反转:原来程序员的主动权要交给用户;需要对外暴露接口(set方法)

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法

(1)在pom.xml 中导入junit 测试依赖

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

(2)在dao层创建接口,以及接口的实现类

  • UserMapper接口
package com.zz.dao;//关于用户的接口
public interface UserMapper {public void getUser();
}
  • 接口的实现类UserMapperImpl
package com.zz.dao.impl;import com.zz.dao.UserMapper;public class UserMapperImpl implements UserMapper {public void getUser() {System.out.println("获取用户数据");}
}
  • 接口的实现类UserMapperMysqlImpl
package com.zz.dao.impl;import com.zz.dao.UserMapper;public class UserMapperMysqlImpl implements UserMapper {public void getUser() {System.out.println("Myaql获取用户数据");}
}

(3)同样在service层(调用dao层)创建接口,以及接口的实现类

  • UserService接口
package com.zz.service;
//用户业务层,本质调用dao层(获取数据),然后在业务层执行操作
public interface UserService {public void getUser();
}
  • 接口的实现类UserServiceImpl
package com.zz.service.impl;import com.zz.dao.UserMapper;
import com.zz.service.UserService;public class UserServiceImpl implements UserService {//调用dao层private UserMapper userMapper;//set方法 只需要对外提供接口 程序不用管理实现public void setUserMapper(UserMapper userMapper) {this.userMapper = userMapper;}public void getUser() {userMapper.getUser();}
}

(4)在test层,创建测试类
用户根据不同的需求进行修改测试类代码

  • 调用UserMapperImpl实现类的方法
    注释掉UserMapperMysqlImpl userMapper = new UserMapperMysqlImpl();这行代码即可
import com.zz.dao.impl.UserMapperImpl;
import com.zz.dao.impl.UserMapperMysqlImpl;
import com.zz.pojo.Hello;
import com.zz.pojo.Student;
import com.zz.service.impl.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;//客户端
public class MyTest {@Testpublic void test1(){//主动权交给用户 想用就去调用接口UserMapperImpl userMapper = new UserMapperImpl();//UserMapperMysqlImpl userMapper = new UserMapperMysqlImpl();UserServiceImpl userService = new UserServiceImpl();userService.setUserMapper(userMapper);userService.getUser();}
}

测试结果:

  • 调用UserMapperMysqlImpl实现类的方法
    注释掉UserMapperImpl userMapper = new UserMapperImpl();这行代码即可
import com.zz.dao.impl.UserMapperImpl;
import com.zz.dao.impl.UserMapperMysqlImpl;
import com.zz.pojo.Hello;
import com.zz.pojo.Student;
import com.zz.service.impl.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;//客户端
public class MyTest {@Testpublic void test1(){//主动权交给用户 想用就去调用接口//UserMapperImpl userMapper = new UserMapperImpl();UserMapperMysqlImpl userMapper = new UserMapperMysqlImpl();UserServiceImpl userService = new UserServiceImpl();userService.setUserMapper(userMapper);userService.getUser();}}

测试结果:

3. HelloSpring

项目目录:

(1)在pom.xml 中导入spring-webmvc依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version>
</dependency>

(2)创建实体类 Hello

package com.zz.pojo;public class Hello {private String name;public void setName(String name) {this.name = name;}public void show(){System.out.println("Hello,"+name);}
}

注意:set方法必须要有

(3)在resources目录下创建配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--注册到Spring Bean就是我们的对象Hello hello = new Hello();hello.setName();id=对象name=属性value=属性值    -->  <bean id="hello" class="com.zz.pojo.Hello"><property name="name" value="Spring"/></bean>
</beans>

(4)编写测试类测试

@Testpublic void test2(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Hello hello = (Hello) context.getBean("hello");hello.show();
}

运行结果:

  • hello 对象是由Spring创建的
  • hello 对象的属性是由Spring容器设置的

4. IOC创建对象的方式

4.1 使用无参构造创建对象(默认)

实体类中需要set方法,配置文件中通过property标签注入

(1)实体类

package com.zz.pojo;public class User {private String name;public User() {System.out.println("对象被创建了");}public void setName(String name) {this.name = name;}public void show(){System.out.println("name="+name);}
}

(2)配置文件

<bean id="user" class="com.zz.pojo.User"><property name="name" value="大佬"/>
</bean>

(3)测试类

 @Testpublic void test3(){//在加载容器时,所有bean就已经被创建了ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");user.show();}

测试结果:

注意:在加载容器时,所有bean就已经被创建了

4.2 使用有参构造创建对象

实体类中需要有参构造方法,配置文件中通过constructor-arg标签注入

(1)实体类

package com.zz.pojo;public class User {private String name;public User(String name) {this.name = name;}public void show(){System.out.println("name="+name);}
}

(2)配置文件

<bean id="user" class="com.zz.pojo.User"><!--有参构造注入--><constructor-arg name="name" value="大佬2"/>
</bean>

(3)测试类
与上面无参测试类相同

@Testpublic void test3(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");user.show();}

测试结果:

5. Spring配置

5.1 别名

<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="userNew"/>

5.2 bean的配置

id : bean 的唯一标识符,也就是相当于我们学的对象名
class : bean 对象所对应的全限定名 : 包名 + 类型
name :也是别名,而且name 可以同时取多个别名

<bean id="user" name="user3 user4 user5" class="com.zz.pojo.User">

5.3 import标签

import一般用于团队开发使用,他可以将多个配置文件,导入合并为一个。

在applicationContext.xml文件中有如下代码,而没有Bean的配置

 <import resource="spring-dao.xml"/>

Bean的配置写在spring-dao.xml文件中

<bean id="user" class="com.zz.pojo.User"><constructor-arg name="name" value="大佬2"/>
</bean>

依然可以获取user对象,测试成功。

6. 属性注入

(1)创建实体类 Address 和Student

package com.zz.pojo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Address{" +"address='" + address + '\'' +'}';}
}
package com.zz.pojo;import java.util.*;public class Student {private String name;private Address address;private String[] books;private List<String> list;private Map<String,String> map;private Set<String> set;private String wife;  //nullprivate Properties info;public void setName(String name) {this.name = name;}public void setAddress(Address address) {this.address = address;}public void setBooks(String[] books) {this.books = books;}public void setList(List<String> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}public void setSet(Set<String> set) {this.set = set;}public void setWife(String wife) {this.wife = wife;}public void setInfo(Properties info) {this.info = info;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", address=" + address +", books=" + Arrays.toString(books) +", list=" + list +", map=" + map +", set=" + set +", wife='" + wife + '\'' +", info=" + info +'}';}
}

(2)配置文件student.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="addr" class="com.zz.pojo.Address"><property name="address" value="安徽"/></bean><bean id="student" class="com.zz.pojo.Student"><!--常量注入--><property name="name" value="大佬"/><!--引用类型 是对象用ref--><property name="address" ref="addr"/><!--数组类型--><property name="books"><array><value>语文</value><value>数学</value><value>英语</value></array></property><!--list类型--><property name="list"><list><value>list1</value><value>list2</value></list></property><!--map类型--><property name="map"><map><entry key="k1" value="v1"/><entry key="k2" value="v2"/></map></property><!--set类型--><property name="set"><set><value>set1</value><value>set2</value></set></property><!--null注入--><property name="wife"><null/></property><!--properties类型--><property name="info"><props><prop key="id">001</prop><prop key="name">zz</prop></props></property></bean></beans>

(3)测试类 MyTest

 @Testpublic void test4(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student) context.getBean("student");System.out.println(student.toString());}

测试结果:

bean的作用域:scope属性
singleton:单例,容器中只存心一个对象(默认)
prototype:非单例,每次创建新对象

<bean id="student" class="com.zz.pojo.Student" scope="prototype">

其余的 request、session、application这些只能在web开发中使用到。

7. 自动装配

手动装配:一个个赋值
自动装配:自动化赋值,不需要一个个赋值

7.1 测试环境搭建

一个人有两个宠物
(1)在java目录下,创建entity包,包下创建三个实体类User、Cat、Dog

package com.zz.entity;public class Cat {public void shout(){System.out.println("miao...");}
}
package com.zz.entity;public class Dog {public void shout(){System.out.println("wang...");}
}
package com.zz.entity;public class User {private String name;private Cat cat;private Dog dog;public void setName(String name) {this.name = name;}public void setCat(Cat cat) {this.cat = cat;}public void setDog(Dog dog) {this.dog = dog;}public String getName() {return name;}public Cat getCat() {return cat;}public Dog getDog() {return dog;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", cat=" + cat +", dog=" + dog +'}';}
}

7.2 byName自动装配

autowire="byName"会自动在容器上下文中查找,和自己对象set方法后面的值对应的 bean id

所以下列代码中,手动配置的那两行可以注释掉

user.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--cat和dog都是引用类型,且没有属性--><bean id="cat" class="com.zz.entity.Cat"/><bean id="dog" class="com.zz.entity.Dog"/><!--自动配置--><bean id="user" class="com.zz.entity.User" autowire="byName"><property name="name" value="大佬"/><!--<property name="cat" ref="cat"/>--><!--<property name="dog" ref="dog"/>--></bean></beans>

MyTest测试类:

@Testpublic void test5(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");System.out.println(user);user.getCat().shout();user.getDog().shout();        }

测试结果:

7.3 byType自动装配

autowire="byType"会自动在容器上下文中查找,和自己对象属性类型相同的bean

只将上述代码中autowire="byName"改为autowire=“byType”,其余代码均与上面相同,测试结果也相同

但是如果这个类型有多个bean,就会报错

小结:

  • byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
  • 在真实的开发中,我们不这么用,而是使用注解实现自动配置

7.4 使用注解实现自动装配

要使用注解须知:

在applicationContext.xml中

  • 导入约束 : context约束
    xmlns:context=“http://www.springframework.org/schema/context”
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">

  • 配置注解的支持 : context:annotation-config/

添加后,完整的applicationContext.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><import resource="user.xml"/></beans>

(1)@Autowired注解

  • 直接在属性上使用即可!也可以在set方式上使用!
  • 使用Autowired 我们可以不用编写Set方法了,前提是你这个自动装配的属性在 IOC(Spring)容器中存在,且符合名字byname!

User类中删除了setCat和setDog方法,添加了@Autowired注解:

package com.zz.entity;import org.springframework.beans.factory.annotation.Autowired;public class User {private String name;@Autowired  //自动装配private Cat cat;@Autowiredprivate Dog dog;public void setName(String name) {this.name = name;}public String getName() {return name;}public Cat getCat() {return cat;}public Dog getDog() {return dog;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", cat=" + cat +", dog=" + dog +'}';}
}

user.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--cat和dog都是引用类型,且没有属性--><bean id="cat" class="com.zz.entity.Cat"/><bean id="dog" class="com.zz.entity.Dog"/><!--自动配置--><bean id="user" class="com.zz.entity.User"><property name="name" value="大佬"/></bean>
</beans>

测试类不变,依然能测出相同的结果

科普:@Nullable 字段标记了这个注解,说明这个字段可以为null;

(2)@Resource注解

public class People {@Resource(name = "cat2")private Cat cat;@Resourceprivate Dog dog;}

小结:
@Resource 和@ Autowired 的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @ Autowired 通过byType的方式实现,而且必须要求这个对象存在! 【常用】
  • @ Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错! 【常用】
  • 执行顺序不同:@ Autowired 通过byType的方式实现。@ Resource 默认通过byname的方式实现

8. 使用注解开发

(1)在Spring4之后,要使用注解开发,必须要保证 aop的包导入了

(2)使用注解需要导入context约束,增加注解的支持!
applicationContext.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><!--扫描包:自动注入所有的组件--><context:component-scan base-package="com.zz.pojo"/></beans>

不用再编写people.xml 文件,不用进行bean标签之类的配置

(3)实体类People:

@Component(“people”) 相当于 : < bean id=“people” …/>
@Value("大哥”)相当于: < property name=“name” value=“大哥”/>
@Scope(“prototype”) 表示作用域,也分为原型模式prototype和单例模式singleton

package com.zz.pojo;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component("people")
@Scope("prototype")
public class People {@Value("大哥")public String name;//也可以放在set方法上// @Value("大哥2")public void setName(String name) {this.name = name;}
}

(4)测试类:

@Testpublic void test6(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");People people = (People) context.getBean("people");System.out.println(people.name);}

测试结果:

衍生的注解

@Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

  • dao 【@Repository】

  • service 【@Service】

  • controller 【@Controller】

    这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

小结:
xml 与 注解:

  • xml 更加万能,适用于任何场合!维护简单方便
  • 注解 不是自己类使用不了,维护相对复杂!

xml 与 注解最佳实践:

  • xml 用来管理bean;
    如: < bean id=“student” class=“com.zz.pojo.Student”/>
  • 注解只负责完成属性的注入;
    如:@Value(“小明”)
    private String name;
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

Spring(三)——HelloSpring、IOC创建对象的方式、属性注入、自动装配、使用注解开发相关推荐

  1. Spring学习3之IOC创建对象的方式

    前言 我们学习了IOC是什么,并且练习了一个Spring程序,知道了对象是由Spring创建,管理,装配.IOC有哪些创建对象的方法呢? 一.IOC创建对象的方式 <!--IOC创建对象的方式 ...

  2. IOC操作Bean管理XML方式(xml自动装配)

    目录 IOC操作Bean管理XML方式(xml自动装配) 一.演示自动装配过程 (1)根据 属性名称 装配 步骤一: 步骤二: 步骤三: (2)根据 属性类型 装配 (2.1)根据 类型 自动装配产生 ...

  3. Spring框架XML配置文件使用外部Bean属性注入

    Spring框架XML配置文件使用外部Bean属性注入 (1)创建两个类service类和dao类 (2)在service中调用dao里面的方法 (3)使用Spring框架进行调用 (4)创建测试类 ...

  4. ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

    上一篇ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器) ,我们说过ASP.NET Core中自带的IOC容器是属于轻量级的,功能并不是很多,只是提供了基础 ...

  5. Spring基础——在 Spring Config 文件中基于 XML 的 Bean 的自动装配

    一.Spring IOC 容器支持自动装配 Bean,所谓自动装配是指,不需要通过 <property> 或 <constructor-arg> 为 Bean 的属性注入值的过 ...

  6. Spring的IOC创建对象的方式和代码基本解释为什么要有ioc的思维以及Ioc容器和spring依赖注入的解释

    首先我们要知道 Ioc是个啥? ​ IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良的程序.传统应用程序都是由我们在类内部主动创建依赖对象,从而导致 ...

  7. Spring IoC、DI、Bean和自动装配的理解

    文章目录 IoC创建对象 DI依赖注入 Bean的理解 自动装配 IoC创建对象 我们都知道IoC是控制反转的,也就是我们只需要把类注册到Spring容器中,他可以帮助我们创建对象,该创建的思想也就是 ...

  8. Spring框架中提取list集合类型属性注入

    提取list集合类型属性注入 前言 引入名称空间 编写`xml`配置文件 运行结果 前言 对于某一个类型属性通用性较高的情况下,可以单独的提取出来,给需要的bean进行引用. 有关类的创建见<S ...

  9. spring学习之将类交给spring管理,bean的注入,scope,集合注入,自动装配,生命周期,迟加载

    一.将类交给spring管理(IOC) 1.将类交给spring容器管理 如何将一个类交给spring容器进行管理呢? 方法很简单,只需要在applicationContext.xml中加入对应的xm ...

最新文章

  1. R语言生存分析COX回归分析实战:两种治疗方法发生肾功能损害的情况
  2. Linux系统(一)文件系统、压缩、打包操作总结
  3. mysql导出表结构 创建_mysql如何导出表结构为文本文件
  4. 国内远程医疗市场快速增长
  5. Javascript单例模式概念与实例
  6. flashfxp链接不上,flashfxp链接不上是因为什么
  7. vba 宏获取文件夹中所有excel文件,对slk文件数据每3000个求平均值
  8. iSCSI发起程序找不到iSCSI_Software_Target_33服务的虚拟磁盘解决办法
  9. python画球matplotlib_python – matplotlib中的球面坐标图
  10. 企业内IT部/信息部发展阶段和趋势(第一阶段)
  11. Muti-Scale Resnet论文初步复现
  12. case when then 后返回多个值
  13. java制作电子钢琴_java 设计 模拟钢琴 完整源码
  14. 随机森林用matlab实现,matlab实现随机森林
  15. Scratch创作-从入门到精通
  16. 前端(JS)windows命令行生成树目录结构和结构图
  17. Web开发必知的八种隔离级别
  18. 【ToB产品经理训练营】笔记
  19. VLC Media Player for Mac(VLC多媒体视频播放器)
  20. RxJava之一——一次性学会使用RxJava

热门文章

  1. cuda学习笔记1 - hello world实战
  2. hust1344(阶层问题+暴力)
  3. uva1504(模拟+暴力)
  4. 观光旅游(Floyd)
  5. AtCoder AGC009E Eternal Average (DP)
  6. hbase查询语句_Sqoop实操|Sqoop导入Parquet文件Hive查询为null问题
  7. JS将数字转换为带有单位的中文表示
  8. Java--Servlet,@ServletSecurity,role,username,password
  9. windows下自制动画层引擎 - 放两个demo
  10. iOS 应用性能测试的相关方法、工具及技巧