河南平台网站建设公司,功能型企业网站有哪些,上海宣传片拍摄制作公司,安居客房产官方网站文章目录基于xml的自动装配①注解②扫描③新建Maven Module④创建Spring配置文件⑤标识组件的常用注解⑥创建组件⑦扫描组件⑧测试⑨组件所对应的bean的id基于注解的自动装配①场景模拟②Autowired注解③Autowired注解其他细节④Autowired工作流程Autowire 注解的原理Qualifier…
文章目录基于xml的自动装配①注解②扫描③新建Maven Module④创建Spring配置文件⑤标识组件的常用注解⑥创建组件⑦扫描组件⑧测试⑨组件所对应的bean的id基于注解的自动装配①场景模拟②Autowired注解③Autowired注解其他细节④Autowired工作流程Autowire 注解的原理Qualifier 注解的使用NoSuchBeanDefinationException基于xml的自动装配
①注解
和 XML 配置文件一样注解本身并不能执行注解本身仅仅只是做一个标记具体的功能是框架检测到注解标记的位置然后针对这个位置按照注解标记的功能来执行具体操作。
本质上所有一切的操作都是Java代码来完成的XML和注解只是告诉框架中的Java代码如何执行。
②扫描
Spring 为了知道程序员在哪些地方标记了什么注解就需要通过扫描的方式来进行检测。然后根据注解进行后续操作。
③新建Maven Module
dependencies!-- 基于Maven依赖传递性导入spring-context依赖即可导入当前所需所有jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.1/version/dependency!-- junit测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency
/dependencies④创建Spring配置文件 ⑤标识组件的常用注解 Component将类标识为普通组件 Controller将类标识为控制层组件 Service将类标识为业务层组件 Repository将类标识为持久层组件 问以上四个注解有什么关系和区别
通过查看源码我们得知Controller、Service、Repository这三个注解只是在Component注解的基础上起了三个新的名字。
对于Spring使用IOC容器管理这些组件来说没有区别。所以Controller、Service、Repository这三个注解只是给开发人员看的让我们能够便于分辨组件的作用。
注意虽然它们本质上一样但是为了代码的可读性为了程序结构严谨我们肯定不能随便胡乱标记。
⑥创建组件
创建控制层组件
Controller
public class UserController {
}创建接口UserService
public interface UserService {
}创建业务层组件UserServiceImpl
Service
public class UserServiceImpl implements UserService {
}创建接口UserDao
public interface UserDao {
}创建持久层组件UserDaoImpl
Repository
public class UserDaoImpl implements UserDao {
}⑦扫描组件
情况一最基本的扫描方式
context:component-scan base-packagecom.atguigu
/context:component-scan情况二指定要排除的组件用得多
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
!--扫描组件--context:component-scan base-packagecom.jxz.spring!-- context:exclude-filter标签指定排除规则 --!--type设置排除或包含的依据typeannotation根据注解排除expression中设置要排除的注解的全类名typeassignable根据类型排除expression中设置要排除的类型的全类名--
!-- context:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/--context:exclude-filter typeassignable expressioncom.jxz.spring.controller.UserController//context:component-scan
/beans情况三仅扫描指定组件
context:component-scan base-packagecom.atguigu use-default-filtersfalse!-- context:include-filter标签指定在原有扫描规则的基础上追加的规则 --!-- use-default-filters属性取值false表示关闭默认扫描规则 --!-- 此时必须设置use-default-filtersfalse因为默认规则即扫描指定包下所有类 --!--type设置排除或包含的依据typeannotation根据注解排除expression中设置要排除的注解的全类名typeassignable根据类型排除expression中设置要排除的类型的全类名--context:include-filter typeannotationexpressionorg.springframework.stereotype.Controller/!--context:include-filter typeassignableexpressioncom.atguigu.controller.UserController/--
/context:component-scan⑧测试
Test
public void testAutowireByAnnotation(){ApplicationContext ac newClassPathXmlApplicationContext(applicationContext.xml);UserController userController ac.getBean(UserController.class);System.out.println(userController);UserService userService ac.getBean(UserService.class);System.out.println(userService);UserDao userDao ac.getBean(UserDao.class);System.out.println(userDao);
}⑨组件所对应的bean的id
在我们使用XML方式管理bean的时候每个bean都有一个唯一标识便于在其他地方引用。现在使用注解后每个组件仍然应该有一个唯一标识。 默认情况 类名首字母小写就是bean的id。例如UserController类对应的bean的id就是userController。 自定义bean的id 可通过标识组件的注解的value属性设置自定义的bean的id Service(“userService”)//默认为userServiceImpl public class UserServiceImpl implementsUserService {} 基于注解的自动装配
①场景模拟 参考基于xml的自动装配 在UserController中声明UserService对象 在UserServiceImpl中声明UserDao对象 ②Autowired注解
**在成员变量上直接标记Autowired注解即可完成自动装配不需要提供setXxx()方法。**以后我们在项目中的正式用法就是这样。
Controller
public class UserController {Autowiredprivate UserService userService;public void saveUser(){userService.saveUser();}
}public interface UserService {void saveUser();
}
Service
public class UserServiceImpl implements UserService {Autowiredprivate UserDao userDao;Overridepublic void saveUser() {userDao.saveUser();}
}public interface UserDao {void saveUser();
} Repository
public class UserDaoImpl implements UserDao {Overridepublic void saveUser() {System.out.println(保存成功);}
}③Autowired注解其他细节 Autowired注解还可以标记在构造器和set方法上完成自动装配 Controller
public class UserController {private UserService userService;Autowiredpublic UserController(UserService userService){this.userService userService;}public void saveUser(){userService.saveUser();}
}Controller
public class UserController {private UserService userService;Autowiredpublic void setUserService(UserService userService){this.userService userService;}public void saveUser(){userService.saveUser();}
}④Autowired工作流程 Autowire 注解的原理 a) 默认通过 byType 的方式在IOC容器中通过类型匹配某个bean为属性赋值如果不存在类型匹配的话直接报NoSuchBeanDefinationException b) 当有多个 bean 的类型能匹配到其会转换为 byName 的方式根据Autowired标记位置成员变量的变量名作为bean的id进行匹配。 c) byType和byName都失效的时候即byType有多个 bean 的类型能匹配到但byName和其中任何一个类型相同的比较id都不一样则报 noUniqueBeanDefinationException. d) 要解决c)可以使用Qualifier注解根据Qualifier注解中指定的名称作为bean的id进行匹配 当执行
Test
public void test3(){ClassPathXmlApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc-annotation.xml);UserController userController ioc.getBean(UserController.class);userController.saveUser();
}其中userService成员变量进行扫描的时候
Autowired
private UserService userService;会找到两个bean类别都为UserService同时默认byName要找的是userService配置的bean的id却为userServiceAAA也不等于userService因此报错:
context:component-scan base-packagecom.jxz.spring/context:component-scan
bean iduserServiceAAA classcom.jxz.spring.service.impl.UserServiceImpl/beanQualifier 注解的使用
我们可以在指定的地方使用下面的注解强行指定要匹配的id
package com.jxz.spring.controller;import com.jxz.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;Controller(jxzController)
public class UserController {AutowiredQualifier(userServiceAAA)private UserService userService;public void saveUser(){userService.saveUser();}
}NoSuchBeanDefinationException 当匹配不到相同类型的Bean完成自动装配的时候会报 NoSuchBeanDefinationException 的错误这是因为Autowire(required true)必须完成自动装配不然直接报错。 当修改为 Autowire(required false) 的时候表示不是必须自动状态找不到Bean则使用默认值和之前使用XML自动装配的时候的情况一样。 比如将依赖的UserDaoImpl注释掉报NoSuchBeanDefinationException
package com.jxz.spring.dao.impl;import com.jxz.spring.dao.UserDao;
import org.springframework.stereotype.Repository;//Repository
public class UserDaoImpl implements UserDao {Overridepublic void saveUser() {System.out.println(保存成功);}
}在对应的调用方修改
Service
public class UserServiceImpl implements UserService {Autowired(required false)private UserDao userDao;public void saveUser(){userDao.saveUser();}
}因为要用到private UserDao userDao但是却不能完成自动装配因此使用默认值null于是 userDao.saveUser();报java.lang.NullPointerException