赞
踩
jdk使用17的版本
pom.xml
- <!--这里必须要加 否则会报版本错误-->
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>6.0.2</version>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <version>5.8.2</version>
- </dependency>
-
- </dependencies>
控制反转(ioc):就是把new对象,交给spring来去new;
依赖注入(di): 就是对控制反转的具体实现
所谓的注入,就是给字段赋值
bean.xml就是对应BeanDefinition,叫做bean定义信息
要想读取这些bean.xml文件的内容就需要一个接口,就是BeanDefinitionReader
然后把这些bean交友ioc来管理
然后解析这些配置
可以通过BeanFactory+反射的方式来实例化(就是new对象)
实例化完,还不能直接使用这个对象,还需要进行初始化
就是set属性赋值
然后你在从上下文中去获取bean就有数据了
我们先来看下set注入
创建bean.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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <!--属性 字段 值-->
- <property name="name" value="张三"></property>
- </bean>
- </beans>
- package com.dmg;
-
- public class A {
-
- private String name;
-
- public A(){
- System.out.println("无参构造A");
- }
-
- public void setName(String name) {
- System.out.println("set注入");
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void add(){
- System.out.println("add");
- }
-
- @Override
- public String toString() {
- return "A{" +
- "name='" + name + '\'' +
- '}';
- }
- }
-
- public class B {
- public static void main(String[] args) {
- ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
-
- A a=(A)context.getBean("a");
- System.out.println(a);
- a.add();
-
-
- }
- }
我们在来看下有参方法构造注入
对A类进行改造
- public A(String name){
- System.out.println("我是有参构造A");
- this.name=name;
- }
修改bean.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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <!--有参构造注入 字段 值-->
- <constructor-arg name="name" value="李四"></constructor-arg>
- </bean>
- </beans>
接下来我们在看下引用其他对象
- package com.dmg;
-
- public class A {
-
- private String name;
-
- private C cc;
-
- public A(){
- System.out.println("无参构造A");
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public C getCc() {
- return cc;
- }
-
- public void setCc(C cc) {
- this.cc = cc;
- }
-
- @Override
- public String toString() {
- return "A{" +
- "name='" + name + '\'' +
- ", cc=" + cc +
- '}';
- }
- }
- package com.dmg;
-
- public class C {
-
- private Integer age;
-
- public C(){
- System.out.println("无参构造c");
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public Integer getAge() {
- return age;
- }
-
- @Override
- public String toString() {
- return "C{" +
- "age=" + age +
- '}';
- }
- }
bean.xml中使用ref引用其他的bean
- <?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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <property name="name" value="张三"></property>
- <property name="cc" ref="c"></property>
- </bean>
-
- <bean id="c" class="com.dmg.C">
- <property name="age" value="18"></property>
- </bean>
-
-
- </beans>
接下来我们在来看下map注入
- package com.dmg;
-
- import java.util.Map;
-
- public class A {
-
- private String name;
-
- private Map<String,C> map;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Map<String, C> getMap() {
- return map;
- }
-
- public void setMap(Map<String, C> map) {
- this.map = map;
- }
-
- @Override
- public String toString() {
- return "A{" +
- "name='" + name + '\'' +
- ", map=" + map +
- '}';
- }
- }
修改bean.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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <property name="name" value="张三"></property>
- <property name="map" >
- <map>
- <entry>
- <key>
- <value>1111</value>
- </key>
- <ref bean="c"></ref>
- </entry>
- <entry>
- <key>
- <value>2222</value>
- </key>
- <ref bean="c"></ref>
- </entry>
- </map>
-
- </property>
- </bean>
-
- <bean id="c" class="com.dmg.C">
- <property name="age" value="18"></property>
- </bean>
-
-
- </beans>
接下来我们在来看下list注入
- package com.dmg;
-
- import java.util.List;
- import java.util.Map;
-
- public class A {
-
- private String name;
-
- private List<C> list;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public List<C> getList() {
- return list;
- }
-
- public void setList(List<C> list) {
- this.list = list;
- }
-
- @Override
- public String toString() {
- return "A{" +
- "name='" + name + '\'' +
- ", list=" + list +
- '}';
- }
- }
修改bean.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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <property name="name" value="张三"></property>
- <property name="list">
- <list>
- <ref bean="c"></ref>
- <ref bean="c"></ref>
- </list>
- </property>
- </bean>
-
- <bean id="c" class="com.dmg.C">
- <property name="age" value="18"></property>
- </bean>
-
-
- </beans>
接下来我们在看下数组注入
- package com.dmg;
-
- import java.util.Arrays;
- import java.util.List;
- import java.util.Map;
-
- public class A {
-
- private String name;
-
- private String[]sz;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String[] getSz() {
- return sz;
- }
-
- public void setSz(String[] sz) {
- this.sz = sz;
- }
-
- @Override
- public String toString() {
- return "A{" +
- "name='" + name + '\'' +
- ", sz=" + Arrays.toString(sz) +
- '}';
- }
- }
修改bean.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">
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <property name="name" value="张三"></property>
- <property name="sz">
- <array>
- <value>1121</value>
- <value>222</value>
- </array>
- </property>
- </bean>
-
-
-
-
- </beans>
接下来我们在来看下util标签注入
修改bean.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:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util.xsd"
-
- >
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A">
- <property name="name" value="张三"></property>
- <property name="list">
- <util:list >
- <ref bean="c"></ref>
- <ref bean="c"></ref>
- </util:list>
- </property>
- </bean>
-
-
- <bean id="c" class="com.dmg.C">
- <property name="age" value="222"></property>
- </bean>
-
- </beans>
接下来我们在看下来p标签 简写注入
修改bean.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:util="http://www.springframework.org/schema/util"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util.xsd"
-
- >
-
- <!--id 随便定义,class 类路径 要在context.getBean("这里匹配上") -->
- <bean id="a" class="com.dmg.A" p:name="张三" p:list-ref="list1">
- </bean>
-
- <util:list id="list1">
- <ref bean="c"></ref>
- <ref bean="c"></ref>
- </util:list>
-
-
- <bean id="c" class="com.dmg.C">
- <property name="age" value="222"></property>
- </bean>
-
- </beans>
接下来我们看下引入外部属性文件
先在pom.xml加入
- <!-- MySQL驱动 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.30</version>
- </dependency>
- <!-- 数据源 -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.2.15</version>
- </dependency>
创建jdbc.properties文件
- jdbc.user=root
- jdbc.password=123456
- jdbc.url=jdbc:mysql://localhost:3306/dmg?serverTimezone=UTC
- jdbc.driver=com.mysql.cj.jdbc.Driver
修改bean.xml文件,使用context标签引入外部文件
- <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/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!--外部文件路径-->
- <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
- <!--引入外部文件 通过占位符赋值-->
- <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
- <property name="username" value="${jdbc.user}"></property>
- <property name="password" value="${jdbc.password}"></property>
- <property name="url" value="${jdbc.url}"></property>
- <property name="driverClassName" value="${jdbc.driver}"></property>
- </bean>
-
- </beans>
然后我们就能动态的修改外部的配置文件了
- public class B {
- public static void main(String[] args) {
- ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
-
- DruidDataSource druidDataSource=(DruidDataSource)context.getBean("druidDataSource");
- System.out.println(druidDataSource.getUrl());
- System.out.println(druidDataSource.getPassword());
-
- }
- }
接下来我们在来看下bean的作用域
pom.xml加入日志
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.13.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>2.13.3</version>
- </dependency>
创建log4j2.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <configuration>
- <loggers>
- <!--
- level指定日志级别,从低到高的优先级:
- TRACE < DEBUG < INFO < WARN < ERROR < FATAL
- trace:追踪,是最低的日志级别,相当于追踪程序的执行
- debug:调试,一般在开发中,都将其设置为最低的日志级别
- info:信息,输出重要的信息,使用较多
- warn:警告,输出警告的信息
- error:错误,输出错误信息
- fatal:严重错误
- -->
- <root level="DEBUG">
- <appender-ref ref="spring6log"/>
- <appender-ref ref="RollingFile"/>
- <appender-ref ref="log"/>
- </root>
- </loggers>
-
- <appenders>
- <!--输出日志信息到控制台-->
- <console name="spring6log" target="SYSTEM_OUT">
- <!--控制日志输出的格式-->
- <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
- </console>
-
- <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
- <File name="log" fileName="d:/spring6_log/test.log" append="false">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
- </File>
-
- <!-- 这个会打印出所有的信息,
- 每次大小超过size,
- 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,
- 作为存档-->
- <RollingFile name="RollingFile" fileName="d:/spring6_log/app.log"
- filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
- <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
- <SizeBasedTriggeringPolicy size="50MB"/>
- <!-- DefaultRolloverStrategy属性如不设置,
- 则默认为最多同一文件夹下7个文件,这里设置了20 -->
- <DefaultRolloverStrategy max="20"/>
- </RollingFile>
- </appenders>
- </configuration>
- public class A {
-
-
- }
bean.xml 使用scope="singleton" 或者不写表示单例
- <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/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <bean id="a" class="com.dmg.A" scope="singleton">
-
- </bean>
- </beans>
我们可以看到在初始化的时候才创建单实例bean,在获取的时候不会创建
2个对象的地址都是一样的,这就是单实例
在bean.xml中改成多实例,scope="prototype"
可以看到2个对象的地址都不一样了
接下来我们来看下bean的生命周期
bean对象创建(调用无参构造器)
给bean对象设置属性
bean的后置处理器(初始化之前)
bean对象初始化(需要在配置bean时指定初始化方法)
bean的后置处理器(初始化之后)
bean对象就绪可以使用
bean对象销毁(需要在配置bean时指定销毁方法)
ioc容器关闭
-
- public class A {
-
-
- public A(){
- System.out.println("1:无参构造");
- }
- private String name;
-
- public void setName(String name) {
- System.out.println("2:属性赋值");
- this.name = name;
- }
-
-
- public void init(){
- System.out.println("4:初始化");
- }
-
- public void xiaoHui(){
- System.out.println("6:销毁");
- }
- }
创建自定义的bean后置处理器,这个后置处理器针对的是所有的ioc容器中的bean
-
- /**
- * 自定义后置处理器
- */
- public class C implements BeanPostProcessor {
-
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("3:初始化之前: "+beanName);
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("5:初始化之后:"+beanName);
- return bean;
- }
- }
-
- public class B {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
-
- A a=(A)context.getBean("a");
- //销毁
- context.close();
- }
- }
创建bean.xml
- <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/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <bean id="a" class="com.dmg.A" init-method="init" destroy-method="xiaoHui">
- <property name="name" value="张三"></property>
- </bean>
-
- <bean id="c" class="com.dmg.C"></bean>
- </beans>
生命周期总结:实例化(创建对象)->属性赋值->初始化->销毁
接下来我们在来看下工厂bean(FactoryBean),
就是可以创建对象,通过&前缀来返回不同的类
- /**
- * 自定义工厂bean
- */
- public class MyFactoryBean implements FactoryBean<A> {
-
-
- //创建对象
- @Override
- public A getObject() throws Exception {
- return new A();
- }
-
- //返回对象类型
- @Override
- public Class<?> getObjectType() {
- return A.class;
- }
- }
修改bean.xml
- <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/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
- <bean id="c" class="com.dmg.C"></bean>
-
- <bean id="myFactoryBean" class="com.dmg.MyFactoryBean"></bean>
-
-
- </beans>
- public class B {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
-
- //加&前缀 返回的就是MyFactoryBean
- System.out.println(context.getBean("&myFactoryBean"));
- //不加前缀 返回的就是A 就是泛型中的类
- System.out.println(context.getBean("myFactoryBean"));
- }
- }
接下来我们在来看下bean的自动装配
自动装配:根据指定的策略 在ioc容器中匹配某一个bean自动为指定的bean中所依赖的类类型或者接口类型 属性赋值
我们先来看下类型注入
- public class MyController {
-
- private MyService myService;
-
- public void setMyService(MyService myService) {
- System.out.println("set注入");
- this.myService = myService;
- }
-
- public void add(){
- System.out.println("控制层");
- myService.add();
- }
-
- }
- public interface MyService {
-
- public void add();
- }
- public class MyServiceImpl implements MyService{
-
- @Override
- public void add() {
- System.out.println("add");
- }
- }
修改bean.xml,使用 autowire="byType"就是根据类型注入
- <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/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
-
- <bean id="myController" class="com.dmg.MyController" autowire="byType">
-
- </bean>
- <bean id="myServiceImpl" class="com.dmg.MyServiceImpl">
-
- </bean>
-
-
-
- </beans>
- public class B {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
- MyController myController=(MyController)context.getBean("myController");
- myController.add();
- }
- }
接下来我们在来看下根据名称注入,改成
autowire="byName"
可以看到报错了,为啥呢?
因为和要这里的myService的名字一样
这次就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。