Loading... # **Spring介绍及IOC ## **目标** 1. **了解Spring及其优点 ** 2. **理解SpringIOC原理** 3. **熟练创建一个Spring 入门案例** ## **一、Spring** **官网 : **[http://spring.io/](http://spring.io/) **官方下载地址 : **[https://repo.spring.io/libs-release-local/org/springframework/spring/](https://repo.spring.io/libs-release-local/org/springframework/spring/) **GitHub : **[https://github.com/spring-projects](https://github.com/spring-projects) ### **1. Spring概述** > **Spring是一个支持快速开发Java EE应用程序的框架。它提供了一系列底层容器和基础设施,并可以和大量常用的开源框架无缝集成,可以说是开发Java EE应用程序的必备。** > >  > > **Spring最早是由Rod Johnson这哥们在他的《**[**Expert One-on-One J2EE Development without EJB**](https://book.douban.com/subject/1426848/)**》一书中提出的用来取代EJB的轻量级框架。随后这哥们又开始专心开发这个基础框架,并起名为Spring Framework。** > > **随着Spring越来越受欢迎,在Spring Framework基础上,又诞生了Spring Boot、Spring Cloud、Spring Data、Spring Security等一系列基于Spring Framework的项目。** > > **简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。** **Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术**  ### **2. spring模块组成(了解)** **Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 **  **组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:** * ****核心容器******:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用*****控制反转*****(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。** * ****Spring 上下文******:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。** * ****Spring AOP******:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。** * ****Spring DAO******:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。** * ****Spring ORM******:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。** * ****Spring Web 模块******:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。** * ****Spring MVC 框架******:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。** ### **3. Spring优点** ****方便解耦,简化开发:**** * **Spring就是一个大工厂,专门负责生成Bean****,可以将所有对象创建和依赖关系维护由Spring管理** ****AOP编程的支持:**** * **Spring提供面向切面编程,可以方便的实现对程序进行****权限拦截****、运行监控等功能** ****声明式事务的支持:**** * **只需要通过配置就可以完成对事务的管理,而无需手动编程** ****方便程序的测试:**** * **Spring对Junit4支持,可以通过注解方便的测试Spring程序** ****方便集成各种优秀框架:**** * **Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的支持** ****降低JavaEE API的使用难度Spring:**** * **对JavaEE开发中一些难用的API(JDBC、JavaMail、远程调webservice用等),都提供了封装,使这些API应用难度大大降低** ## **二、IOC容器** > **在学习Spring框架时,我们遇到的第一个也是最核心的概念就是容器。** > > **什么是容器?容器是一种为某种特定组件的运行提供必要支持的一个软件环境。例如,Tomcat就是一个Servlet容器,它可以为Servlet的运行提供运行环境。类似Docker这样的软件也是一个容器,它提供了必要的Linux环境以便运行一个特定的Linux进程。** > > **通常来说,使用容器运行组件,除了提供一个组件运行环境之外,容器还提供了许多底层服务。例如,Servlet容器底层实现了TCP连接,解析HTTP协议等非常复杂的服务,如果没有容器来提供这些服务,我们就无法编写像Servlet这样代码简单,功能强大的组件。早期的JavaEE服务器提供的EJB容器最重要的功能就是通过声明式事务服务,使得EJB组件的开发人员不必自己编写冗长的事务处理代码,所以极大地简化了事务处理。** > > **Spring的核心就是提供了一个IoC容器,它可以管理所有轻量级的JavaBean组件,提供的底层服务包括组件的生命周期管理、配置和组装服务、AOP支持,以及建立在AOP基础上的声明式事务服务等。** ### **1. IOC原理** **Spring提供的容器又称为IoC容器,什么是IoC?** **IoC全称Inversion of Control,直译为控制反转。那么何谓IoC?在理解IoC之前,我们先看看通常的Java组件是如何协作的。** 1. **创建一个UserDao接口** ``` public interface UserDao { /** *功能描述: 获取用户信息 * @author jiaoqianjin * @date 2021/3/12 */ void getUser(); } ``` 2. **创建Dao的实现类** ``` public class UserDaoImpl implements UserDao { public void getUser() { System.out.println("获取用户数据"); } } ``` 3. **编写UserService的接口** ``` public interface UserService { /** *功能描述:获取用户信息 * @author jiaoqianjin * @date 2021/3/12 */ void getUser(); } ``` 4. **编写Service的实现类** ``` public class UserServiceImpl implements UserService { UserMysqlImpl userDao = new UserMysqlImpl(); /** * 功能描述:获取用户信息 * * @author jiaoqianjin * @date 2021/3/12 */ public void getUser() { userDao.getUser(); } } ``` 5. **测试** ``` public class UserTest { @Test public void testUser(){ UserService service = new UserServiceImpl(); service.getUser(); } } ``` **上述的逻辑是正常的一个获取一个用户信息的流程,现在我们修改一下,再去根据UserDao接口实现一个类,返回不同的信息** ``` public class UserMysqlImpl implements UserDao { public void getUser() { System.out.println("从mysql中获取数据"); } } ``` **紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现** ``` public class UserServiceImpl implements UserService { // UserDaoImpl userDao = new UserDaoImpl(); UserMysqlImpl userDao = new UserMysqlImpl(); /** * 功能描述:获取用户信息 * * @author jiaoqianjin * @date 2021/3/12 */ public void getUser() { userDao.getUser(); } } ``` **在假设, 我们再增加一个Userdao的实现类 ** ``` public class UserDaoOracleImpl implements UserDao { /** * 功能描述: 获取用户信息 * * @author jiaoqianjin * @date 2021/3/12 */ public void getUser() { System.out.println("从Oracle获取数据"); } } ``` **那么我们要使用Oracle , 又需要去service实现类里面修改对应的实现 . 假设我们的这种需求非常大 , 这种方式就根本不适用了** **从上面的例子可以看出,如果一个系统有大量的组件,其生命周期和相互之间的依赖关系如果由组件自身来维护,不但大大增加了系统的复杂度,而且会导致组件之间极为紧密的耦合,继而给测试和维护带来了极大的困难。** **因此,核心问题是:** 1. **谁负责创建组件?** 2. **谁负责根据依赖关系组装组件?** 3. **销毁时,如何按依赖顺序正确销毁?** **解决这一问题的核心方案就是IoC。** **传统的应用程序中,控制权在程序本身,程序的控制流程完全由开发者控制,例如:** `UserServiceImpl`**创建了**`UserMysqlImpl`**组件,使用Oracle实现的时候又需要创建**`UserDaoOracleImpl`**组件,这种模式的缺点是,一个组件如果要使用另一个组件,必须先知道如何正确地创建它。** ****如何解决?**** **在IoC模式下,控制权发生了反转,即从应用程序转移到了IoC容器,所有组件不再由应用程序自己创建和配置,而是由IoC容器负责,这样,应用程序只需要直接使用已经创建好并且配置好的组件。为了能让组件在IoC容器中被“装配”出来,需要某种“注入”机制,** **例如,**`UserServiceImpl`**自己并不会创建userDao,而是等待外部通过**`setUserDao()`**方法来注入一个**`userDao`**:** **我们可以在需要用到它的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下** ``` public class UserServiceImpl implements UserService { // UserDaoImpl userDao = new UserDaoImpl(); // UserMysqlImpl userDao = new UserMysqlImpl(); private UserDao userDao; /** * 功能描述: 利用set注入 * * @param userDao 接口实现类 * @author jiaoqianjin * @date 2021/3/12 */ public void setUserDao(UserDao userDao) { this.userDao = userDao; } /** * 功能描述:获取用户信息 * * @author jiaoqianjin * @date 2021/3/12 */ public void getUser() { userDao.getUser(); } } ``` **测试** ``` @Test public void testUser1() { UserServiceImpl service = new UserServiceImpl(); // 使用mysql实现 service.setUserDao(new UserMysqlImpl()); service.getUser(); //那我们现在又想用Oracle去实现呢 service.setUserDao(new UserDaoOracleImpl()); service.getUser(); } ``` **不直接**`new`**一个**`UserDao`**,而是注入一个**`UserDao`**,这个小小的改动虽然简单,却带来了一系列好处: ** **以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .** **这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 !** **因此,IoC又称为**`依赖注入`**(DI:Dependency Injection),它解决了一个最主要的问题:将组件的创建+配置与组件的使用相分离,并且,由IoC容器负责管理组件的生命周期。** **因为IoC容器要负责实例化所有的组件,因此,有必要告诉容器如何创建组件,以及各组件的依赖关系。一种最简单的配置是通过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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans> ``` #### **依赖注入方式** **我们从上面的代码可以看到,依赖注入可以通过**`set()`**方法实现。但依赖注入也可以通过构造方法实现。** **很多Java类都具有带参数的构造方法,如果我们把**`UserDao`**改造为通过构造方法注入,那么实现代码如下:** ``` public class UserServiceImpl implements UserService { private UserDao userDao; /** * 功能描述: 利用构造方法注入 * * @param userDao 接口实现类 * @author jiaoqianjin * @date 2021/3/12 */ public UserServiceImpl(UserDao userDao) { this.userDao = userDao } /** * 功能描述:获取用户信息 * * @author jiaoqianjin * @date 2021/3/12 */ public void getUser() { userDao.getUser(); } } ``` **Spring的IoC容器同时支持属性注入和构造方法注入,并允许混合使用。** #### **无侵入容器** **在设计上,Spring的IoC容器是一个高度可扩展的无侵入容器。所谓无侵入,是指应用程序的组件无需实现Spring的特定接口,或者说,组件根本不知道自己在Spring的容器中运行。这种无侵入的设计有以下好处:** 1. **应用程序组件既可以在Spring的IoC容器中运行,也可以自己编写代码自行组装配置;** 2. **测试的时候并不依赖Spring容器,可单独进行测试,大大提高了开发效率。** ## **三、Spring入门** ### **1. 入门案例** #### **1. 导入Maven依赖** ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.10.RELEASE</version> </dependency> ``` #### **2. 编写一个User实体类** ``` public class User { private Integer id; private String name; private String phone; public void show(){ System.out.println("Hello,"+ name ); } } ``` #### **3. 编写一个Spring文件** **beans.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就是java对象 , 由Spring创建和管理--> <bean id="user" class="com.shida.entity.User"> <property name="name" value="焦前进"/> </bean> </beans> ``` #### **4. 测试** ``` @Test public void test(){ //解析beans.xml文件 , 生成管理相应的Bean对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //getBean : 参数即为spring配置文件中bean的id . User user = (User) context.getBean("user"); user.show(); } ``` **回到我们的IOC原理案例** **新增一个Spring配置文件beans.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="MysqlImpl" class="com.shida.dao.impl.UserMysqlImpl"/> <bean id="OracleImpl" class="com.shida.dao.impl.UserDaoOracleImpl"/> <bean id="ServiceImpl" class="com.shida.service.impl.UserServiceImpl"> <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写--> <!--引用另外一个bean , 不是用value 而是用 ref--> <property name="userDao" ref="OracleImpl"/> </bean> </beans> ``` **测试** ``` @Test public void testUser2(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("ServiceImpl"); serviceImpl.getUser(); } ``` **OK , 到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 ! ** ### **2. IOC创建对象方式** #### **1. 通过无参构造方法创建** ##### **1. User实体类** ``` public class User { private Integer id; private String name; private String phone; public User() { System.out.println("user无参构造方法"); } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+ name ); } } ``` ##### **2. beans.xml** ``` <bean id="user" class="com.shida.entity.User"> <property name="name" value="焦前进"/> </bean> ``` ##### **3. 测试类** ``` @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //在执行getBean的时候, user已经创建好了 , 通过无参构造 User user = (User) context.getBean("user"); //调用对象的方法 . user.show(); } ``` **结果可以发现,在调用show方法之前,User对象已经通过无参构造初始化了** #### **2. 通过有参构造创建** ##### **1. User实体类** ``` public class User { private Integer id; private String name; private String phone; // public User() { // System.out.println("user无参构造方法"); // } public User(String name) { System.out.println("user有参构造方法"); this.name = name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+ name ); } } ``` ##### **2. beans.xml** **①根据index参数下标设置** ``` <!-- 第一种根据index参数下标设置 --> <bean id="user" class="com.shida.entity.User"> <!-- index指构造方法 , 下标从0开始 --> <constructor-arg index="0" value="焦前进"/> </bean>``` ``` **②根据参数名字设置** ``` <!-- 第二种根据参数名字设置 --> <bean id="user" class="com.shida.entity.User"> <!-- name指参数名 --> <constructor-arg name="name" value="焦前进"/> </bean> ``` **③根据参数类型设置** ``` <!-- 第三种根据参数类型设置 --> <bean id="user" class="com.shida.entity.User"> <constructor-arg type="java.lang.String" value="焦前进"/> </bean> ``` ### **3. Spring配置** #### **1. 别名** ``` <!--设置别名:在获取Bean的时候可以使用别名获取--> <alias name="user" alias="userNew"/> ``` #### **2. Bean的配置** ``` <!--bean就是java对象,由Spring创建和管理--> <!-- id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符 如果配置id,又配置了name,那么name是别名 name可以设置多个别名,可以用逗号,分号,空格隔开 如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象; class是bean的全限定名=包名+类名 --> <bean id="user" name="user" class="com.shida.entity.User"> <property name="name" value="焦前进"/> </bean> ``` ## **四、依赖注入(手动装配)** **依赖注入(Dependency Injection,DI)。** * **依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .** * **注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .** ### **1. 构造器注入** ### **2. Set方法注入** #### **1. 创建Address与Student实体类** ``` public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } } ``` ``` public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; // set get toString() } ``` #### **2.注入 applicationContext.xml** ``` <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="addr" class="com.shida.entity.Address"> <property name="address" value="河南新乡"/> </bean> <bean id="student" class="com.shida.entity.Student"> <!-- 1. 常量注入--> <property name="name" value="焦前进"/> <!-- 2. bean注入--> <property name="address" ref="addr"/> <!-- 3. 数组注入--> <property name="books"> <array> <value>Java入门很简单</value> <value>Mysql入门很简单</value> </array> </property> <!-- 4. 集合注入--> <property name="hobbys"> <list> <value>打篮球</value> <value>写bug</value> </list> </property> <!-- 5. map注入--> <property name="card"> <map> <entry key="邮政" value="123456"></entry> <entry key="建设" value="654321"></entry> </map> </property> <!-- 6. set注入--> <property name="games"> <set> <value>王者荣耀</value> <value>和平精英</value> </set> </property> <!-- 7. null注入--> <property name="wife"><null/></property> <!-- 8. properties注入--> <property name="info"> <props> <prop key="学号">20170624215</prop> <prop key="姓名">焦前进</prop> </props> </property> </bean> </beans> ``` #### **3. 测试** ``` public class StudentTest { @Test public void test1() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) applicationContext.getBean("student"); System.out.println(JSONUtil.toJsonPrettyStr(student)); } } ``` **推荐hutool工具类 ** [**HuTool使用文档**](https://www.hutool.cn/docs/#/json/JSONUtil?id=readxxx) ``` <!-- hutool的java开发工具包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.6.3</version> </dependency> ``` ### **3. 注解注入** **1、在spring配置文件中引入context文件头** ``` <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> ``` ## **五、注解注入** ### **1. 新建dog、cat、people实体类** ``` @ToString public class Cat { public void shout() { System.out.println("miao~"); } } ``` ``` @ToString public class Dog { public void shout() { System.out.println("wang~"); } } ``` ``` @ToString public class User { private Cat cat; private Dog dog; private String str; // set get } ``` ### **2. beans.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 id="dog" class="com.shida.entity.Dog"/> <bean id="cat" class="com.shida.entity.Cat"/> <bean id="user" class="com.shida.entity.User"> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> <property name="str" value="焦前进"/> </bean> </beans> ``` ### **3. 测试** ``` public class UserTest { @Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); User user = applicationContext.getBean("user", User.class); user.getCat().shout(); user.getDog().shout(); } ``` ### **4. 使用注解 修改** **将User类中的set方法去掉,使用@Autowired注解** ``` @ToString public class User { @Autowired private Cat cat; @Autowired private Dog dog; private String str; public Cat getCat() { return cat; } public Dog getDog() { return dog; } public String getStr() { return str; } } ``` **在spring配置文件中引入context文件头** ``` xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ``` **完整的spring配置文件** ``` <?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"> <!--开启属性注解支持!--> <context:annotation-config/> <bean id="dog" class="com.shida.entity.Dog"/> <bean id="cat" class="com.shida.entity.Cat"/> <bean id="user" class="com.shida.entity.User"/> </beans> ``` ## **六、使用注解开发** ### **1. spring配置** ``` <?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.xsd"> </beans> ``` **我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!** ### **2、配置扫描哪些包下的注解** ``` <!--指定注解扫描包--> <context:component-scan base-package="com.shida.entity"/> ``` ### **3、在指定包下编写类,增加注解** ``` @Component("user") // 相当于配置文件中 <bean id="user" class="当前注解的类"/> public class User {} ``` ### **4. 属性注入** **使用注解注入属性** **1、可以不用提供set方法,直接在直接名上添加@value("值")**  **2、如果提供了set方法,在set方法上添加@value("值");**  ****@Component三个衍生注解**** **为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。** * **@Controller:web层** * **@Service:service层** * **@Repository:dao层** **写上这些注解,就相当于将这个类交给Spring管理装配了!** ### **5. 总结** ****XML与注解比较**** * **XML可以适用任何场景 ,结构清晰,维护方便** * **注解不是自己提供的类使用不了,开发简单方便** ****xml与注解整合开发****** :推荐最佳实践** * **xml管理Bean** * **注解完成属性注入** * **使用过程中, 可以不用扫描,扫描是为了类上的注解** ``` <context:annotation-config/> ``` **作用:** * **进行注解驱动注册,从而使注解生效** * **用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册** * **如果不扫描包,就需要手动配置bean** * **如果不加注解驱动,则注入的值为null** Last modification:June 27th, 2021 at 03:29 pm © 允许规范转载