spring6-多种类型的注入方式
OCP原则ocp指开闭原则对扩展开放对修改关闭。是七大原则中最基本的一个原则。依赖倒置原则DIP什么是依赖倒置原则核心是面向接口编程、面向抽象编程 不是面向具体编程。依赖倒置原则的目的降低耦合度提高扩展力什么是控制反转控制反转IocInversion of Controll一种编程思想、设计模式。为了降低程序耦合度反转有两点不在程序中采用硬编码的方式new对象把创建对象交给别人UserService userService new UserServiceImplForMysql()。不在程序中采用硬编码的方式维护对象关系。spring框架spring实现了Ioc因此可以创建和维护对象见的关系。控制反转实现方式主要有依赖注入Dependency Injection DI依赖注入的方式有以下方式Set注入执行Set方法赋值构造方法注入执行构造方法赋值依赖注入中的“依赖”、“注入”的含义依赖A对象和B对象的关系注入是一种手段通过这种手段让A和B产生关系。依赖注入的实现方式有set注入和构造方法注入。set注入配置文件配置bean!-- 配置dao-- bean iduserDao classcom.ali.dao.UserDao /bean !-- 配置Service-- bean iduserService classcom.ali.service.UserService !--注入dao这里的name是 set方法名去掉set字符后剩下的单词首字母小写-- !-- ref后面指定要注入的bean的id-- property nameuserDao refuserDao/ /bean在类中写set方法package com.ali.service; import com.ali.dao.UserDao; public class UserService { private UserDao userDao; // set注入需要提供一个set方法方法名以set开头spring容器调用这个set方法注入UserDao public void setUserDao(UserDao userDao) { this.userDao userDao; } public void saveUser(){ userDao.insertUser(); } }这样即可注入成功。注入外部bean!-- 声明bean-- bean idorderDao classcom.ali.dao.OrderDao / bean idorderService classcom.ali.service.OrderService !-- 使用ref 来 注入外部bean-- property nameorderDao reforderDao/ /bean注入内部beanbean idorderService2 classcom.ali.service.OrderService property nameorderDao !-- 在property标签中使用嵌套bean这就是内部bean-- bean classcom.ali.dao.OrderDao /bean /property /bean注入简单类型!-- 注入简单类型属性-- bean iduserBean classcom.ali.bean.User !-- 简单类型赋值使用value属性-- property namename value张三/property property nameage value30/property property namepassword value123456/property /bean实际开发中一般不会吧Date类型当作简单类型会使用ref来注入Date类型级联属性赋值!-- 使用级联属性赋值给studentBean的clazz属性赋值必须有set、get方法-- !-- 先配置clazz 再配置clazz.name-- bean idstudentBean classcom.ali.bean.Student property namename value李四/property property nameclazz refclazzBean/property !--级联属性赋值给studentBean的clazz属性赋值 这里的clazz是Student类中的属性名 clazz 必须有set、get方法-- property nameclazz.name value高三二班/property /bean bean idclazzBean classcom.ali.bean.Clazz /bean注入数组!-- 注入简单类型属性-- bean iduserBean1 classcom.ali.bean.User !-- 简单类型赋值使用value属性-- property namename value张三/property property nameage value30/property property namepassword value123456/property /bean bean iduserBean2 classcom.ali.bean.User !-- 简单类型赋值使用value属性-- property namename value张三/property property nameage value30/property property namepassword value123456/property /bean bean iduserBean3 classcom.ali.bean.User !-- 简单类型赋值使用value属性-- property namename value张三/property property nameage value30/property property namepassword value123456/property /bean bean idqdyBean classcom.ali.bean.QDY !-- aihao属性是一个字符串数组-- property nameaihao array value吃/value value喝/value /array /property !-- friends是一个User对象数组-- property namefriends array ref beanuserBean1/ref ref beanuserBean2/ref ref beanuserBean3/ref /array /property /bean注入List和Set类型bean idpersonBean classcom.ali.bean.Person !-- names是 ListString 类型-- property namenames list value张三/value value里斯/value value詹姆思/value /list /property !-- address 是 SetString 类型-- property nameaddress set value北京/value value上海/value value广州/value /set /property /bean注入Map集合!-- phone 是一个MapInteger, String类型 如果key是简单类型可以直接使用entry标签的key属性赋值 如果key是复杂类型可以使用 entry key-refkeyBean value-refvalueBean/entry value同理-- property namephone map entry key1 value13800138000/entry entry key2 value13900139000/entry entry key3 value13700137000/entry /map /property注入Properties类型!-- Properties 的key 和value只能是字符串类型-- property nameproperties props prop keyk1v1/prop prop keyk2v2/prop prop keyk3v3/prop /props /property注入null和空字符串!-- 以下是手动注入null-- property namename null/null /property !-- 不给属性注入属性的默认值是null-- !-- property namename valuetom/property-- !-- 注入空字符串方式一 -- property namename value/property !-- 注入空字符串方式二 -- property namename value/value /property property nameage value“31”/property注入特殊字符串bean idmathBean classcom.ali.bean.MathBean !-- 第一种使用实体符号代替特殊符号 23 -- !-- property nameresult value2 lt; 3/property-- !-- 第二种使用![CDATA[]] 这里面的内容不会被xml解析 23 -- property nameresult !-- 只能使用value标签-- value![CDATA[23]]/value /property /bean构造注入配置文件配置beanbean iduserDaoBean classcom.ali.dao.UserDao /bean !-- 构造注入-- bean classcom.ali.service.CustomerService idcustomerService !-- 指定构造方法的第一个参数下标是0-- constructor-arg index0 refuserDaoBean/constructor-arg !-- 根据参数名注入-- constructor-arg nameuserDao refuserDaoBean“/constructor-arg /bean在类中写构造方法public class CustomerService { private UserDao userDao; public CustomerService(UserDao userDao) { this.userDao userDao; } public void save(){ userDao.insertUser(); } }p命名空间注入简化set注入!-- p命名空间注入底层还是set注入类中的属性必须有set方法只不过p命名空间注入让spring配置更加简单 1.在spring配置文件头部添加p命名空间。 xmlns:phttp://www.springframework.org/schema/p 2.使用p命名空间注入属性语法p:属性名属性值 p:属性名-ref引用类型属性值-- bean iddogBean classcom.ali.bean.Dog p:age22 p:name张三 p:birthday-refbirthdayBean/ bean idbirthdayBean classjava.util.Date /c命名空间注入简化构造注入!-- c命名空间注入底层还是构造器注入类中必须有对应的构造器只不过c命名空间注入让spring配置更加简单 1.在spring配置文件头部添加c命名空间。 xmlns:chttp://www.springframework.org/schema/c 2.使用c命名空间注入属性语法c:属性名属性值 c:属性名-ref引用类型属性值 c:_0 下标方式 c:name 参数名方式-- bean idpeopleBean classcom.ali.bean.People c:name咪咪 c:age3 c:sextrue/基于xml的自动装配byName!-- 自动装配byName、 也是基于set的-- !-- 根据名字自动装配其中OrderDao是OrderService里面的一个属性。必须有set方法-- bean idorderServiceBean classcom.ali.service.OrderService autowirebyName/bean !-- 这个id 必须是OrderService中set方法去掉“set”后首字母小写-- bean idorderDao classcom.ali.dao.OrderDao/bean基于xml的自动装配byType!-- 根据类型自动装配自动装配是基于set方法的 根据类型进行自动装配时配置文件中某个类型的实例只能有一个 -- bean classcom.ali.dao.VipDao/bean bean classcom.ali.dao.UserDao/bean !-- CustomerService类里面VipDao和UserDao属性这2个属性必须有set方法才能自动注入上面2个bean-- bean idcustomerServiceBean classcom.ali.service.CustomerService autowirebyType/bean /beans引入外部的属性配置文件!-- 引入外部的properties文件 第一步引入context命名空间 xmlns:contexthttp://www.springframework.org/schema/context http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 第二步使用context:property-placeholder标签引入外部的properties文件,默认从类的根路径下加载 -- context:property-placeholder locationclasspath:jdbc.properties/ bean idmydataSource classcom.ali.bean.MyDataSource !-- 使用${}占位符引用外部properties文件中的属性值 这4个属性必须有set方法-- property namedriver value${jdbc.diverClass}/ property nameurl value${jdbc.url}/ property nameusername value${jdbc.username}/ property namepassword value${jdbc.password}/ /beanjdbc.properties文件jdbc.diverClasscom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/spring6db?useSSLfalseserver jdbc.usernameroot jdbc.password123456spring怎么实例化对象默认情况下spring通过反射机制调用类的无参数构造方法实例化对象把创建好的对象存储到Map结构中。当有多个配置文件时可读取多个配置文件ApplicationContext context new ClassPathXmlApplicationContext(spring.xml,spring-dao.xml);可以在配置文件中注入jdk自带的类只要这个类有无参数构造方法就行。getBean时Bean的id不存在时会报错从类路径之外的路径获取xml配置文件// 读取类路径之外的配置文件 ApplicationContext context new FileSystemXmlApplicationContext(D:/applicationContext.xml); Object user context.getBean(user); // 获取spring容器中的对象ApplicationContext的超级父接口是BeanFactory。BeanFactory是Ioc容器的顶级接口。spring的Ioc容器底层使用了工厂模式。启用Log4j2spring5之后支持Log4j2框架。引入依赖dependency groupIdorg.apache.logging.log4j/groupId artifactIdlog4j-slf4j2-impl/artifactId version2.19.0/version /dependency dependency groupIdorg.apache.logging.log4j/groupId artifactIdlog4j-core/artifactId version2.19.0/version /dependency编写配置文件文件名必须是log4j2.xml放在类根路径下?xml version1.0 encodingUTF-8? configuration loggers !-- level指定日志级别从低到高的优先级 ALL TRACE DEBUG INFO WARN ERROR FATAL OFF -- root levelDEBUG appender-ref refspring6log/ /root /loggers appenders !--输出日志信息到控制台-- console namespring6log targetSYSTEM_OUT !--控制日志输出的格式-- PatternLayout pattern%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n/ /console /appenders /configuration使用日志框架 在SpringTest01类中使用如下代码Logger logger LoggerFactory.getLogger(SpringTest01.class); logger.info(日志信息);