当前位置:   article > 正文

spring6入门之ioc-基于xml方式注入_spring6可否xml注入

spring6可否xml注入

jdk使用17的版本

pom.xml 

  1. <!--这里必须要加 否则会报版本错误-->
  2. <properties>
  3. <maven.compiler.source>17</maven.compiler.source>
  4. <maven.compiler.target>17</maven.compiler.target>
  5. </properties>
  6. <dependencies>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-context</artifactId>
  10. <version>6.0.2</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.junit.jupiter</groupId>
  14. <artifactId>junit-jupiter-api</artifactId>
  15. <version>5.8.2</version>
  16. </dependency>
  17. </dependencies>

控制反转(ioc):就是把new对象,交给spring来去new;

依赖注入(di): 就是对控制反转的具体实现

所谓的注入,就是给字段赋值

bean.xml就是对应BeanDefinition,叫做bean定义信息

要想读取这些bean.xml文件的内容就需要一个接口,就是BeanDefinitionReader

然后把这些bean交友ioc来管理

然后解析这些配置

可以通过BeanFactory+反射的方式来实例化(就是new对象)

实例化完,还不能直接使用这个对象,还需要进行初始化

就是set属性赋值

然后你在从上下文中去获取bean就有数据了

我们先来看下set注入

创建bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <!--属性 字段 值-->
  8. <property name="name" value="张三"></property>
  9. </bean>
  10. </beans>

  1. package com.dmg;
  2. public class A {
  3. private String name;
  4. public A(){
  5. System.out.println("无参构造A");
  6. }
  7. public void setName(String name) {
  8. System.out.println("set注入");
  9. this.name = name;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void add(){
  15. System.out.println("add");
  16. }
  17. @Override
  18. public String toString() {
  19. return "A{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  1. public class B {
  2. public static void main(String[] args) {
  3. ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  4. A a=(A)context.getBean("a");
  5. System.out.println(a);
  6. a.add();
  7. }
  8. }

 我们在来看下有参方法构造注入

对A类进行改造

  1. public A(String name){
  2. System.out.println("我是有参构造A");
  3. this.name=name;
  4. }

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <!--有参构造注入 字段 值-->
  8. <constructor-arg name="name" value="李四"></constructor-arg>
  9. </bean>
  10. </beans>

 接下来我们在看下引用其他对象

  1. package com.dmg;
  2. public class A {
  3. private String name;
  4. private C cc;
  5. public A(){
  6. System.out.println("无参构造A");
  7. }
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public C getCc() {
  15. return cc;
  16. }
  17. public void setCc(C cc) {
  18. this.cc = cc;
  19. }
  20. @Override
  21. public String toString() {
  22. return "A{" +
  23. "name='" + name + '\'' +
  24. ", cc=" + cc +
  25. '}';
  26. }
  27. }
  1. package com.dmg;
  2. public class C {
  3. private Integer age;
  4. public C(){
  5. System.out.println("无参构造c");
  6. }
  7. public void setAge(Integer age) {
  8. this.age = age;
  9. }
  10. public Integer getAge() {
  11. return age;
  12. }
  13. @Override
  14. public String toString() {
  15. return "C{" +
  16. "age=" + age +
  17. '}';
  18. }
  19. }

bean.xml中使用ref引用其他的bean

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <property name="name" value="张三"></property>
  8. <property name="cc" ref="c"></property>
  9. </bean>
  10. <bean id="c" class="com.dmg.C">
  11. <property name="age" value="18"></property>
  12. </bean>
  13. </beans>

接下来我们在来看下map注入 

  1. package com.dmg;
  2. import java.util.Map;
  3. public class A {
  4. private String name;
  5. private Map<String,C> map;
  6. public String getName() {
  7. return name;
  8. }
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. public Map<String, C> getMap() {
  13. return map;
  14. }
  15. public void setMap(Map<String, C> map) {
  16. this.map = map;
  17. }
  18. @Override
  19. public String toString() {
  20. return "A{" +
  21. "name='" + name + '\'' +
  22. ", map=" + map +
  23. '}';
  24. }
  25. }

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <property name="name" value="张三"></property>
  8. <property name="map" >
  9. <map>
  10. <entry>
  11. <key>
  12. <value>1111</value>
  13. </key>
  14. <ref bean="c"></ref>
  15. </entry>
  16. <entry>
  17. <key>
  18. <value>2222</value>
  19. </key>
  20. <ref bean="c"></ref>
  21. </entry>
  22. </map>
  23. </property>
  24. </bean>
  25. <bean id="c" class="com.dmg.C">
  26. <property name="age" value="18"></property>
  27. </bean>
  28. </beans>

接下来我们在来看下list注入

  1. package com.dmg;
  2. import java.util.List;
  3. import java.util.Map;
  4. public class A {
  5. private String name;
  6. private List<C> list;
  7. public String getName() {
  8. return name;
  9. }
  10. public void setName(String name) {
  11. this.name = name;
  12. }
  13. public List<C> getList() {
  14. return list;
  15. }
  16. public void setList(List<C> list) {
  17. this.list = list;
  18. }
  19. @Override
  20. public String toString() {
  21. return "A{" +
  22. "name='" + name + '\'' +
  23. ", list=" + list +
  24. '}';
  25. }
  26. }

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <property name="name" value="张三"></property>
  8. <property name="list">
  9. <list>
  10. <ref bean="c"></ref>
  11. <ref bean="c"></ref>
  12. </list>
  13. </property>
  14. </bean>
  15. <bean id="c" class="com.dmg.C">
  16. <property name="age" value="18"></property>
  17. </bean>
  18. </beans>

接下来我们在看下数组注入

  1. package com.dmg;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.Map;
  5. public class A {
  6. private String name;
  7. private String[]sz;
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public String[] getSz() {
  15. return sz;
  16. }
  17. public void setSz(String[] sz) {
  18. this.sz = sz;
  19. }
  20. @Override
  21. public String toString() {
  22. return "A{" +
  23. "name='" + name + '\'' +
  24. ", sz=" + Arrays.toString(sz) +
  25. '}';
  26. }
  27. }

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  6. <bean id="a" class="com.dmg.A">
  7. <property name="name" value="张三"></property>
  8. <property name="sz">
  9. <array>
  10. <value>1121</value>
  11. <value>222</value>
  12. </array>
  13. </property>
  14. </bean>
  15. </beans>

接下来我们在来看下util标签注入

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:util="http://www.springframework.org/schema/util"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/util
  7. http://www.springframework.org/schema/util/spring-util.xsd"
  8. >
  9. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  10. <bean id="a" class="com.dmg.A">
  11. <property name="name" value="张三"></property>
  12. <property name="list">
  13. <util:list >
  14. <ref bean="c"></ref>
  15. <ref bean="c"></ref>
  16. </util:list>
  17. </property>
  18. </bean>
  19. <bean id="c" class="com.dmg.C">
  20. <property name="age" value="222"></property>
  21. </bean>
  22. </beans>

接下来我们在看下来p标签 简写注入

修改bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:util="http://www.springframework.org/schema/util"
  5. xmlns:p="http://www.springframework.org/schema/p"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/util
  8. http://www.springframework.org/schema/util/spring-util.xsd"
  9. >
  10. <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
  11. <bean id="a" class="com.dmg.A" p:name="张三" p:list-ref="list1">
  12. </bean>
  13. <util:list id="list1">
  14. <ref bean="c"></ref>
  15. <ref bean="c"></ref>
  16. </util:list>
  17. <bean id="c" class="com.dmg.C">
  18. <property name="age" value="222"></property>
  19. </bean>
  20. </beans>

接下来我们看下引入外部属性文件

先在pom.xml加入

  1. <!-- MySQL驱动 -->
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. <version>8.0.30</version>
  6. </dependency>
  7. <!-- 数据源 -->
  8. <dependency>
  9. <groupId>com.alibaba</groupId>
  10. <artifactId>druid</artifactId>
  11. <version>1.2.15</version>
  12. </dependency>

创建jdbc.properties文件

  1. jdbc.user=root
  2. jdbc.password=123456
  3. jdbc.url=jdbc:mysql://localhost:3306/dmg?serverTimezone=UTC
  4. jdbc.driver=com.mysql.cj.jdbc.Driver

修改bean.xml文件,使用context标签引入外部文件

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/context
  5. http://www.springframework.org/schema/context/spring-context.xsd
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <!--外部文件路径-->
  9. <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
  10. <!--引入外部文件 通过占位符赋值-->
  11. <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
  12. <property name="username" value="${jdbc.user}"></property>
  13. <property name="password" value="${jdbc.password}"></property>
  14. <property name="url" value="${jdbc.url}"></property>
  15. <property name="driverClassName" value="${jdbc.driver}"></property>
  16. </bean>
  17. </beans>

然后我们就能动态的修改外部的配置文件了

  1. public class B {
  2. public static void main(String[] args) {
  3. ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  4. DruidDataSource druidDataSource=(DruidDataSource)context.getBean("druidDataSource");
  5. System.out.println(druidDataSource.getUrl());
  6. System.out.println(druidDataSource.getPassword());
  7. }
  8. }

接下来我们在来看下bean的作用域

pom.xml加入日志

  1. <dependency>
  2. <groupId>org.apache.logging.log4j</groupId>
  3. <artifactId>log4j-core</artifactId>
  4. <version>2.13.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.logging.log4j</groupId>
  8. <artifactId>log4j-slf4j-impl</artifactId>
  9. <version>2.13.3</version>
  10. </dependency>

创建log4j2.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <loggers>
  4. <!--
  5. level指定日志级别,从低到高的优先级:
  6. TRACE < DEBUG < INFO < WARN < ERROR < FATAL
  7. trace:追踪,是最低的日志级别,相当于追踪程序的执行
  8. debug:调试,一般在开发中,都将其设置为最低的日志级别
  9. info:信息,输出重要的信息,使用较多
  10. warn:警告,输出警告的信息
  11. error:错误,输出错误信息
  12. fatal:严重错误
  13. -->
  14. <root level="DEBUG">
  15. <appender-ref ref="spring6log"/>
  16. <appender-ref ref="RollingFile"/>
  17. <appender-ref ref="log"/>
  18. </root>
  19. </loggers>
  20. <appenders>
  21. <!--输出日志信息到控制台-->
  22. <console name="spring6log" target="SYSTEM_OUT">
  23. <!--控制日志输出的格式-->
  24. <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
  25. </console>
  26. <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
  27. <File name="log" fileName="d:/spring6_log/test.log" append="false">
  28. <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
  29. </File>
  30. <!-- 这个会打印出所有的信息,
  31. 每次大小超过size
  32. 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,
  33. 作为存档-->
  34. <RollingFile name="RollingFile" fileName="d:/spring6_log/app.log"
  35. filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
  36. <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
  37. <SizeBasedTriggeringPolicy size="50MB"/>
  38. <!-- DefaultRolloverStrategy属性如不设置,
  39. 则默认为最多同一文件夹下7个文件,这里设置了20 -->
  40. <DefaultRolloverStrategy max="20"/>
  41. </RollingFile>
  42. </appenders>
  43. </configuration>
  1. public class A {
  2. }

bean.xml 使用scope="singleton" 或者不写表示单例

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/context
  5. http://www.springframework.org/schema/context/spring-context.xsd
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <bean id="a" class="com.dmg.A" scope="singleton">
  9. </bean>
  10. </beans>

 我们可以看到在初始化的时候才创建单实例bean,在获取的时候不会创建

2个对象的地址都是一样的,这就是单实例

 在bean.xml中改成多实例,scope="prototype"

可以看到2个对象的地址都不一样了

接下来我们来看下bean的生命周期


bean对象创建(调用无参构造器)
给bean对象设置属性
bean的后置处理器(初始化之前)
bean对象初始化(需要在配置bean时指定初始化方法)
bean的后置处理器(初始化之后)
bean对象就绪可以使用
bean对象销毁(需要在配置bean时指定销毁方法)
ioc容器关闭

  1. public class A {
  2. public A(){
  3. System.out.println("1:无参构造");
  4. }
  5. private String name;
  6. public void setName(String name) {
  7. System.out.println("2:属性赋值");
  8. this.name = name;
  9. }
  10. public void init(){
  11. System.out.println("4:初始化");
  12. }
  13. public void xiaoHui(){
  14. System.out.println("6:销毁");
  15. }
  16. }

创建自定义的bean后置处理器,这个后置处理器针对的是所有的ioc容器中的bean

  1. /**
  2. * 自定义后置处理器
  3. */
  4. public class C implements BeanPostProcessor {
  5. @Override
  6. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  7. System.out.println("3:初始化之前: "+beanName);
  8. return bean;
  9. }
  10. @Override
  11. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  12. System.out.println("5:初始化之后:"+beanName);
  13. return bean;
  14. }
  15. }
  1. public class B {
  2. public static void main(String[] args) {
  3. ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  4. A a=(A)context.getBean("a");
  5. //销毁
  6. context.close();
  7. }
  8. }

创建bean.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/context
  5. http://www.springframework.org/schema/context/spring-context.xsd
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <bean id="a" class="com.dmg.A" init-method="init" destroy-method="xiaoHui">
  9. <property name="name" value="张三"></property>
  10. </bean>
  11. <bean id="c" class="com.dmg.C"></bean>
  12. </beans>

生命周期总结:实例化(创建对象)->属性赋值->初始化->销毁 

接下来我们在来看下工厂bean(FactoryBean),

就是可以创建对象,通过&前缀来返回不同的类

  1. /**
  2. * 自定义工厂bean
  3. */
  4. public class MyFactoryBean implements FactoryBean<A> {
  5. //创建对象
  6. @Override
  7. public A getObject() throws Exception {
  8. return new A();
  9. }
  10. //返回对象类型
  11. @Override
  12. public Class<?> getObjectType() {
  13. return A.class;
  14. }
  15. }

修改bean.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/context
  5. http://www.springframework.org/schema/context/spring-context.xsd
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <bean id="c" class="com.dmg.C"></bean>
  9. <bean id="myFactoryBean" class="com.dmg.MyFactoryBean"></bean>
  10. </beans>
  1. public class B {
  2. public static void main(String[] args) {
  3. ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  4. //加&前缀 返回的就是MyFactoryBean
  5. System.out.println(context.getBean("&myFactoryBean"));
  6. //不加前缀 返回的就是A 就是泛型中的类
  7. System.out.println(context.getBean("myFactoryBean"));
  8. }
  9. }

接下来我们在来看下bean的自动装配 

自动装配:根据指定的策略 在ioc容器中匹配某一个bean自动为指定的bean中所依赖的类类型或者接口类型 属性赋值

我们先来看下类型注入

  1. public class MyController {
  2. private MyService myService;
  3. public void setMyService(MyService myService) {
  4. System.out.println("set注入");
  5. this.myService = myService;
  6. }
  7. public void add(){
  8. System.out.println("控制层");
  9. myService.add();
  10. }
  11. }
  1. public interface MyService {
  2. public void add();
  3. }
  1. public class MyServiceImpl implements MyService{
  2. @Override
  3. public void add() {
  4. System.out.println("add");
  5. }
  6. }

修改bean.xml,使用 autowire="byType"就是根据类型注入

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/context
  5. http://www.springframework.org/schema/context/spring-context.xsd
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd">
  8. <bean id="myController" class="com.dmg.MyController" autowire="byType">
  9. </bean>
  10. <bean id="myServiceImpl" class="com.dmg.MyServiceImpl">
  11. </bean>
  12. </beans>
  1. public class B {
  2. public static void main(String[] args) {
  3. ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  4. MyController myController=(MyController)context.getBean("myController");
  5. myController.add();
  6. }
  7. }

 接下来我们在来看下根据名称注入,改成

autowire="byName"

可以看到报错了,为啥呢?

 因为和要这里的myService的名字一样

 这次就可以了

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/90462
推荐阅读
相关标签
  

闽ICP备14008679号