Java笔记:Spring配置xml和注解

简介: Java笔记:Spring配置xml和注解

Spring

Java Web发展历史

  • 第一阶段 JavaBean + Servlet + JSP
  • 第二阶段 EJB重量级框架
  • 第三阶段 SpringMVC/Struts + Spring + Hibernate/MyBatis
  • 第四阶段 SpringBoot 约定大于配置
  • 第五阶段 Dubbo为代表的SOA微服务架构体系
  • 第六阶段 SpringCloud 微服务框架爱技术生态圈

课程内容IoC

  • 介绍IoC并编写一个简单的IoC容器
  • 介绍通过xml方式完成SpringIoC对Bean的管理
  • 介绍SpringIoC相关注解的使用

IoC介绍

IoC Inversion of Control 控制反转,依赖注入

控制:控制对象的创建及销毁(生命周期)

反转:将对象的控制权交给IoC容器

简化约定

  • 所有的Bean的生命周期都交由IoC容器管理
  • 所有被依赖的Bean通过构造函数方法执行注入被依赖的Bean需要优先创建

IoC实现

依赖关系

Car
    +start()
    +stop()
    +turnLeft()
    +turnRight()
    <- AudiCar
    <- BuickCar
Human
    +goHome()
    <- HumanWithCar
        -car
        +goHome()
        <- LisiHuman
        <- ZhangsanHuman

代码实现

package com.demo.ioc.car;
/**
 * 汽车
 */
public interface Car {
    void start();
    void stop();
    void turnLeft();
    void turnRight();
}
package com.demo.ioc.car;
/**
 * 奥迪车
 */
public class AudiCar implements Car{
    @Override
    public void start() {
        System.out.println("AudiCar start");
    }
    @Override
    public void stop() {
        System.out.println("AudiCar stop");
    }
    @Override
    public void turnLeft() {
        System.out.println("AudiCar turnLeft");
    }
    @Override
    public void turnRight() {
        System.out.println("AudiCar turnRight");
    }
}
package com.demo.ioc.car;
/**
 * 别克车
 */
public class BuickCar implements Car{
        @Override
        public void start() {
            System.out.println("BuickCar start");
        }
        @Override
        public void stop() {
            System.out.println("BuickCar stop");
        }
        @Override
        public void turnLeft() {
            System.out.println("BuickCar turnLeft");
        }
        @Override
        public void turnRight() {
            System.out.println("BuickCar turnRight");
    }
}
package com.demo.ioc.human;
/**
 * 人类接口
 */
public interface Human {
    void goHome();
}
package com.demo.ioc.human;
import com.demo.ioc.car.Car;
/**
 * 有车人
 */
public abstract class HumanWithCar implements Human {
    protected Car car;
    public HumanWithCar(Car car) {
        this.car = car;
    }
    public abstract void goHome();
}
package com.demo.ioc.human;
import com.demo.ioc.car.Car;
/**
 * 张三
 */
public class ZhangsanHuman extends HumanWithCar{
    public ZhangsanHuman(Car car) {
        super(car);
    }
    @Override
    public void goHome() {
        this.car.start();
        this.car.turnLeft();
        this.car.stop();
    }
}
package com.demo.ioc.human;
import com.demo.ioc.car.Car;
/**
 * 李四
 */
public class LisiHuman extends HumanWithCar{
    public LisiHuman(Car car) {
        super(car);
    }
    @Override
    public void goHome() {
        this.car.start();
        this.car.turnRight();
        this.car.stop();
    }
}
package com.demo.ioc;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 1. 实例化Bean
 * 2. 保存Bean
 * 3. 提供Bean
 * 4. 每个Bean要与唯一的id对应
 */
public class IocContainer {
    private Map<String, Object> beans = new ConcurrentHashMap<>();
    /**
     * 根据 beanId获取Bean
     *
     * @param beanId
     * @return
     */
    public Object getBean(String beanId) {
        return beans.get(beanId);
    }
    /**
     * 委托IoC容器创建一个Bean
     *
     * @param clazz        Bean的class
     * @param beanId       Bean 的id
     * @param paramBeanIds class构造函数所需参数的beanId
     */
    public void setBean(Class<?> clazz, String beanId, String... paramBeanIds) {
        //  1. 组装构造方法所需要的参数值
        Object[] paramBeans = new Object[paramBeanIds.length];
        for (int i = 0; i < paramBeanIds.length; i++) {
            paramBeans[i] = beans.get(paramBeanIds[i]);
        }
        //  2. 调用构造方法实例化Bean
        Object bean = null;
        for (Constructor<?> constructor: clazz.getConstructors()){
            try {
                bean = constructor.newInstance(paramBeans);
            } catch (InstantiationException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
        if(bean == null){
            throw new RuntimeException("Bean实例化失败");
        }
        //  3. 将示例化的bean放入beans
        beans.put(beanId, bean);
    }
}

代码回顾

所有的依赖关系被集中统一的管理起来,清晰明了

每个类只需要关注自己的业务逻辑

修改依赖关系将是一件很容易的事情

Spring IoC

依赖pom.xml

 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.7.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.7.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>
package com.demo.ioc;
public class Bean {
}

spring.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交由Spring创建并管理-->
    <bean id="bean" class="com.demo.ioc.Bean"/>
</beans>

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean(){
        // 获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        // 获取bean
        Bean bean = context.getBean("bean", Bean.class);
        System.out.println(bean);
    }
}

实例化Bean方式

  • 通过构造方法实例化Bean
  • 通过静态方法实例化Bean
  • 通过实例方法实例化Bean
  • Bean的别名

1、通过构造方法实例化Bean

package com.demo.ioc;
public class Bean {
    public Bean(){}
}
<bean id="bean" class="com.demo.ioc.Bean"/>

2、通过静态方法实例化Bean

package com.demo.ioc;
public class BeanFactory {
    public static Bean createBean(){
        return new Bean();
    }
}
<bean id="bean" class="com.demo.ioc.BeanFactory" factory-method="createBean"/>

3、通过实例方法实例化Bean

package com.demo.ioc;
public class BeanFactory {
    public Bean createBean(){
        return new Bean();
    }
}
<bean id="beanFactory" class="com.demo.ioc.BeanFactory"/>
<bean id="bean" class="com.demo.ioc.Bean" factory-bean="beanFactory" factory-method="createBean"/>

4、Bean的别名

<bean id="bean" class="com.demo.ioc.Bean" name="bean1,bean2"/>
<!-- alias不支持逗号分隔 -->
<alias name="bean" alias="bean3"/>

注入Bean方式

通过构造方法注入Bean

通过set方式注入Bean

集合类Bean的注入(List、Set、Map、Properties)

null注入

注入时创建内部Bean

1、通过构造方法注入Bean

package com.demo.ioc;
public class Bean {
    private String name;
    private AnotherBean anotherBean;
    public Bean(String name, AnotherBean anotherBean) {
        this.name = name;
        this.anotherBean = anotherBean;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public AnotherBean getAnotherBean() {
        return anotherBean;
    }
    public void setAnotherBean(AnotherBean anotherBean) {
        this.anotherBean = anotherBean;
    }
    @Override
    public String toString() {
        return "Bean{" +
                "name='" + name + '\'' +
                ", anotherBean=" + anotherBean +
                '}';
    }
}
package com.demo.ioc;
public class AnotherBean {
}
<bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
<bean id="bean" class="com.demo.ioc.Bean">
    <!-- index、name、type三个属性组合确定参数 -->
    <!-- value用于简单数据类型 -->
    <!-- ref用于复杂数据类型 -->
    <constructor-arg index="0" name="name" type="java.lang.String" value="Tom"/>
    <constructor-arg index="1" name="anotherBean" type="com.demo.ioc.AnotherBean" ref="anotherBean"/>
</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"
       xmlns:c="http://www.springframework.org/schema/c"
       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">
    <bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
    <bean id="bean" class="com.demo.ioc.Bean"
          c:name="Jack" c:anotherBean-ref="anotherBean"/>
</beans>

2、通过set方式注入Bean

package com.demo.ioc;
public class Bean {
    private String name;
    private AnotherBean anotherBean;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public AnotherBean getAnotherBean() {
        return anotherBean;
    }
    public void setAnotherBean(AnotherBean anotherBean) {
        this.anotherBean = anotherBean;
    }
    @Override
    public String toString() {
        return "Bean{" +
                "name='" + name + '\'' +
                ", anotherBean=" + anotherBean +
                '}';
    }
}
<bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
<bean id="bean" class="com.demo.ioc.Bean">
    <property name="name" value="Jack"/>
    <property name="anotherBean" ref="anotherBean"/>
</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"
       xmlns:c="http://www.springframework.org/schema/c"
       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">
    <bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
    <bean id="bean" class="com.demo.ioc.Bean"
          p:name="Jack" p:anotherBean-ref="anotherBean"/>
</beans>

3、集合类Bean的注入(List、Set、Map、Properties)

package com.demo.ioc;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Bean {
    private List<String> stringList;
    private List<AnotherBean> anotherBeanList;
    private Set<String> stringSet;
    private Set<AnotherBean> anotherBeanSet;
    private Map<String, String> stringMap;
    private Map<String, AnotherBean> anotherBeanMap;
    private Properties properties;
    private AnotherBean anotherBean1;
    private AnotherBean anotherBean2;
    public void setAnotherBean1(AnotherBean anotherBean1) {
        this.anotherBean1 = anotherBean1;
    }
    public void setAnotherBean2(AnotherBean anotherBean2) {
        this.anotherBean2 = anotherBean2;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }
    public void setAnotherBeanList(List<AnotherBean> anotherBeanList) {
        this.anotherBeanList = anotherBeanList;
    }
    public void setStringSet(Set<String> stringSet) {
        this.stringSet = stringSet;
    }
    public void setAnotherBeanSet(Set<AnotherBean> anotherBeanSet) {
        this.anotherBeanSet = anotherBeanSet;
    }
    public void setStringMap(Map<String, String> stringMap) {
        this.stringMap = stringMap;
    }
    public void setAnotherBeanMap(Map<String, AnotherBean> anotherBeanMap) {
        this.anotherBeanMap = anotherBeanMap;
    }
}
<bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
<bean id="bean" class="com.demo.ioc.Bean">
    <property name="stringList">
        <list>
            <value>Tom</value>
            <value>Jack</value>
        </list>
    </property>
    <property name="anotherBeanList">
        <list>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </list>
    </property>
    <property name="stringSet">
        <set>
            <value>Tom</value>
            <value>Jack</value>
        </set>
    </property>
    <property name="anotherBeanSet">
        <set>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </set>
    </property>
    <property name="stringMap">
        <map>
            <entry key="name" value="Tom"/>
            <entry key="age" value="23"/>
        </map>
    </property>
    <property name="anotherBeanMap">
        <map>
           <entry key="name" value-ref="anotherBean"/>
           <entry key="age" value-ref="anotherBean"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="name">Tom</prop>
        </props>
    </property>
    <property name="anotherBean1">
        <!-- null注入 -->
        <null/>
    </property>
    <property name="anotherBean2">
        <!-- 注入时创建内部Bean -->
        <bean class="com.demo.ioc.AnotherBean"/>
    </property>
</bean>
<bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
<bean id="bean" class="com.demo.ioc.Bean">
    <property name="stringList">
        <list>
            <value>Tom</value>
            <value>Jack</value>
        </list>
    </property>
    <property name="anotherBeanList">
        <list>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </list>
    </property>
    <property name="stringSet">
        <set>
            <value>Tom</value>
            <value>Jack</value>
        </set>
    </property>
    <property name="anotherBeanSet">
        <set>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </set>
    </property>
    <property name="stringMap">
        <map>
            <entry key="name" value="Tom"/>
            <entry key="age" value="23"/>
        </map>
    </property>
    <property name="anotherBeanMap">
        <map>
           <entry key="name" value-ref="anotherBean"/>
           <entry key="age" value-ref="anotherBean"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="name">Tom</prop>
        </props>
    </property>
    <property name="anotherBean1">
        <!-- null注入 -->
        <null/>
    </property>
    <property name="anotherBean2">
        <!-- 注入时创建内部Bean -->
        <bean class="com.demo.ioc.AnotherBean"/>
    </property>
</bean>
<bean id="anotherBean" class="com.demo.ioc.AnotherBean"/>
<bean id="bean" class="com.demo.ioc.Bean">
    <property name="stringList">
        <list>
            <value>Tom</value>
            <value>Jack</value>
        </list>
    </property>
    <property name="anotherBeanList">
        <list>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </list>
    </property>
    <property name="stringSet">
        <set>
            <value>Tom</value>
            <value>Jack</value>
        </set>
    </property>
    <property name="anotherBeanSet">
        <set>
            <ref bean="anotherBean"/>
            <ref bean="anotherBean"/>
        </set>
    </property>
    <property name="stringMap">
        <map>
            <entry key="name" value="Tom"/>
            <entry key="age" value="23"/>
        </map>
    </property>
    <property name="anotherBeanMap">
        <map>
           <entry key="name" value-ref="anotherBean"/>
           <entry key="age" value-ref="anotherBean"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="name">Tom</prop>
        </props>
    </property>
    <property name="anotherBean1">
        <!-- null注入 -->
        <null/>
    </property>
    <property name="anotherBean2">
        <!-- 注入时创建内部Bean -->
        <bean class="com.demo.ioc.AnotherBean"/>
    </property>
</bean>

Bean作用域

  • singleton作用域(单例,限定在一个上下文环境中)
  • prototype作用域(多例)
  • Web环境作用域
  • request作用域
  • session作用域
  • application作用域
  • websocket作用域
  • 自定义作用域
  • SimpleThreadScope作用域
<!-- 单例 默认singleton -->
<bean id="bean" class="com.demo.ioc.Bean"/>
<!-- 多例 -->
<bean id="bean" class="com.demo.ioc.Bean" scope="prototype"/>

总结

配置

<bean id="bean2" class="com.demo.ioc.Bean2" scope="prototype"/>
<bean id="bean1" class="com.demo.ioc.Bean1">
    <property name="bean2" ref="bean2"/>
</bean>

-

Bean1-singleton

Bean1-prototype

Bean2-singleton

bean1单实例、bean2单实例

bean1多实例、bean2单实例

Bean2-prototype

bean1单实例、bean2单实例

bean1多实例、bean2多实例


方法注入

场景:

Bean1是singleton, Bean2是prototype, Bean1依赖于Bean2

我们希望每次调用Bean1某个方法时候,该方法每次拿到Bean2都是新的实例

package com.demo.ioc;
public class Bean2 {
}
package com.demo.ioc;
public abstract class Bean1 {
    protected abstract Bean2 createBean2();
}
<bean id="bean2" class="com.demo.ioc.Bean2" scope="prototype"/>
<bean id="bean1" class="com.demo.ioc.Bean1" scope="singleton">
    <lookup-method name="createBean2" bean="bean2"/>
</bean>

Web环境作用域

项目结构

$ tree
.
├── pom.xml
└── src
   └── main
      ├── java
      │   └── com
      │       └── demo
      │           ├── ApplicationController.java
      │           ├── RequestController.java
      │           └── SessionController.java
      ├── resources
      │   └── spring.xml
      └── webapp
          └── WEB-INF
              └── web.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>spring-mvc</groupId>
    <artifactId>com.demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--打包方式为war-->
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
    </dependencies>
</project>

web.xml

<?xml version="1.0" encoding="utf-8" ?>
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>
    <!-- 建立SpringWeb上下文环境-->
    <servlet>
        <servlet-name>SpringServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

RequestController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class RequestController {
    @RequestMapping("/request")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}

SessionController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SessionController {
    @RequestMapping("/session")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}

ApplicationController.java

package com.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ApplicationController {
    @RequestMapping("/application")
    @ResponseBody
    public String test(){
        return this.toString();
    }
}

总结

reuqest:每个request请求都会创建一个单独的实例。

session:每个session都会创建一个单独的实例。

application:每个sercletContext都会创建一个单独的实例。

websocket:每个websocket链接都会创建一个单独的实例。

自定义作用域

双例模式

package com.demo.ioc;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 自定义作用域
 * 实现双例模式(每一个Bean对应两个实例)
 */
public class MyScope implements Scope {
    Map<String, Object> map1 = new ConcurrentHashMap<>();
    Map<String, Object> map2 = new ConcurrentHashMap<>();
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        //先从map1取
        if (!map1.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map1.put(name, obj);
            return obj;
        }
        //再从map2取
        if (!map2.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map2.put(name, obj);
            return obj;
        }
        // 如果map1和map2中都存在则随机返回
        int i = new Random().nextInt(2);
        if (i == 0) {
            return map1.get(name);
        } else {
            return map2.get(name);
        }
    }
    @Override
    public Object remove(String name) {
        // 和添加顺序正好相反
        if(map2.containsKey(name)){
            Object obj = map2.get(name);
            map2.remove(name);
            return obj;
        }
        if(map1.containsKey(name)){
            Object obj = map1.get(name);
            map1.remove(name);
            return obj;
        }
        return null;
    }
    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
    }
    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }
    @Override
    public String getConversationId() {
        return null;
    }
}
package com.demo.ioc;
public class 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"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/jee
                        http://www.springframework.org/schema/jee/spring-jee.xsd">
    <bean id="myScope" class="com.demo.ioc.MyScope"/>
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="myScope" value-ref="myScope"/>
            </map>
        </property>
    </bean>
    <bean class="com.demo.ioc.Bean" id="bean" scope="myScope"/>
</beans>

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean(){
        // 获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        for (int i = 0; i < 10; i++) {
            Bean bean = context.getBean("bean", Bean.class);
            System.out.println(bean);
        }
    }
}

simpleThreadScope

每个线程都会创建一个单独的实例

<!--单线程中只有一个实例-->
<bean id="simpleThreadScope" class="org.springframework.context.support.SimpleThreadScope"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="simpleThreadScope" value-ref="simpleThreadScope"/>
        </map>
    </property>
</bean>
<bean class="com.demo.ioc.Bean" id="bean" scope="simpleThreadScope"/>
package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean(){
        // 获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        for (int i = 0; i < 10; i++) {
            Bean bean = context.getBean("bean", Bean.class);
            System.out.println(bean);
        }
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Bean bean = context.getBean("bean", Bean.class);
                    System.out.println(bean);
                }
            }).start();
        }
    }
}

Bean的懒加载

Spring容器会在创建容器时,提前初始化Singleton(单例)作用域的bean,

但是如果Bean被标注了lazy-init=“true”,

则该Bean只有在其在被需要的时候才会被初始化。


注意:只对Singleton(单例)作用域的bean有效,其他作用域如多例并不知道什么这个bean才会被需要实例化。


为某个Bean设定为懒加载

<bean class="com.demo.ioc.Bean" id="bean" lazy-init="true"/>

为所有Bean设定为懒加载

<beans default-lazy-init="true">
    <bean class="com.demo.ioc.Bean" id="bean"/>
</beans>

适用场景

如果某个Bean在程序整个运行周期都可能不会被使用,那么可考虑设定该Bean为懒加载。

优点:尽可能的节省了资源。

缺点:可能会导致某个操作响应时间增加。

Bean的初始化及销毁逻辑处理

1、如果需要在Bean实例化之后执行一些逻辑,有两种方法:

  • 使用init-method属性
  • 让Bean实现InitializingBean接口
  • 2、如果需要在Bean销毁之前执行一些逻辑,有两种方法:
  • 使用destory-method属性
  • 让Bean实现DisposableBean接口

3、通过指定方法名实现

package com.demo.ioc;
public class Bean {
    public void onInit(){
        System.out.println("onInit");
    }
    public void onDestroy(){
        System.out.println("onDestroy");
    }
}

单个Bean初始化和销毁方法执行

<bean class="com.demo.ioc.Bean" id="bean" init-method="onInit" destroy-method="onDestroy"/>

所有Bean初始化和销毁方法执行

<beans 
       default-init-method="onInit"
       default-destroy-method="onDestroy"
>
    <bean class="com.demo.ioc.Bean" id="bean" />
</beans>
package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean(){
        // 获取上下文
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        // 关闭上下文
        context.close();
    }
}

4、通过实现接口

package com.demo.ioc;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Bean implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}

Bean属性继承

package com.demo.ioc;
public class Parent {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
package com.demo.ioc;
public class Child1 extends Parent{
    private String name1;
    public String getName1() {
        return name1;
    }
    public void setName1(String name1) {
        this.name1 = name1;
    }
    @Override
    public String toString() {
        return "Child1{" +
                "name='" + getName() + '\'' +
                "name1='" + name1 + '\'' +
                '}';
    }
}
package com.demo.ioc;
public class Child2 extends Parent{
    private String name2;
    public String getName2() {
        return name2;
    }
    public void setName2(String name2) {
        this.name2 = name2;
    }
    @Override
    public String toString() {
        return "Child1{" +
                "name='" + getName() + '\'' +
                "name2='" + name2 + '\'' +
                '}';
    }
}

继承关系配置

<!-- 这个javaBean不需要实例化 -->
<bean id="parent" class="com.demo.ioc.Parent" abstract="true">
    <property name="name" value="name"/>
</bean>
<bean id="child1" class="com.demo.ioc.Child1" parent="parent">
    <property name="name1" value="name1"/>
</bean>
<bean id="child2" class="com.demo.ioc.Child2" parent="parent">
    <property name="name2" value="name1"/>
</bean>

或者非继承关系,有相同的属性

<bean id="parent" abstract="true">
    <property name="name" value="name"/>
</bean>
<bean id="child1" class="com.demo.ioc.Child1" parent="parent">
    <property name="name1" value="name1"/>
</bean>
<bean id="child2" class="com.demo.ioc.Child2" parent="parent">
    <property name="name2" value="name1"/>
</bean>

SpringIoC注解的基本使用

pom.xml依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

1、使用xml文件

package com.demo.ioc;
public class Bean{
}

创建spring.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交由Spring创建并管理 -->
    <bean id="bean" class="com.demo.ioc.Bean"/>
</beans>

获取Bean

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        // 获取Bean
        Bean bean = context.getBean("bean", Bean.class);
        System.out.println(bean);
    }
}

2、使用annotation

package com.demo.ioc;
public class Person {
}

package com.demo.ioc.human;
import com.demo.ioc.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 创建配置文件
@Configuration
public class MyConfiguration {
    // 将Bean交由Spring创建并管理
    // name参数可以省略,默认方法名就是bean的名称
    @Bean(name = "person")
    public Person person(){
        return new Person();
    }
}

获取Bean

package com.demo.ioc;
import com.demo.ioc.human.MyConfiguration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        ApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        // 获取Bean
        Person bean = context.getBean("person", Person.class);
        System.out.println(bean);
    }
}

包扫描

1、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: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"
>
    <!--开启包扫描-->
    <context:component-scan base-package="com.demo.ioc"/>
</beans>

2、注解方式

package com.demo.ioc;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
// 设置需要扫描的包
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
}
package com.demo.ioc;
import org.springframework.stereotype.Component;
// 增加注解后会被Spring扫描到, 默认的Id是类名首字母小写
@Component(value = "person")
public class Person {
}

注解

@Component     // 通用型注解
@Controller    // Controller层
@Service       // Service层
@Repository    // Dao层

Bean别名

xml形式

<bean id="person" name="person1, person2" class="com.demo.ioc.Person"/>
<alias name="person" alias="person3"/>

注解方式

package com.demo.ioc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
public class MyConfiguration {
    @Bean(name = {"person1", "person2"})
    public Person person(){
        return new Person();
    }
}

通过注解注入Bean

通过方法注入Bean

通过构造方法注入Bean

通过Set方法注入Bean

通过属性注入Bean

集合类Bean类型注入

直接注入集合实例

将多个泛型的实例注入到集合

将多个泛型实例注入到List

控制泛型示实例在List中的顺序

将多个泛型的实例注入到Map

String、Integer等类型直接赋值

SpringIoC容器内置接口示例注入

准备Bean

package com.demo.ioc;
import org.springframework.stereotype.Component;
@Component
public class Cat {
}
package com.demo.ioc;
import org.springframework.stereotype.Component;
@Component
public class Dog {
}
package com.demo.ioc;
import org.springframework.stereotype.Component;
@Component
public class Pig {
}

配置文件

package com.demo.ioc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean(name = "stringList")
    public List<String> stringList() {
        List<String> list = new ArrayList<>();
        list.add("Tom");
        list.add("Jack");
        return list;
    }
    // 此优先级高于 List<String>
    @Bean
    @Order(2) // 指定优先级
    public String string1(){
        return "string1";
    }
    @Bean
    @Order(1)
    public String string2(){
        return "string2";
    }
    @Bean
    public Map<String, Integer> stringIntegerMap(){
        Map<String, Integer> map = new HashMap<>();
        map.put("dog", 23);
        map.put("pig", 24);
        return map;
    }
    // 优先级高于 Map<String, Integer>
    @Bean
    public Integer integer1(){
        return 222;
    }
    @Bean
    public Integer integer2(){
        return 223;
    }
}

注入实例

package com.demo.ioc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class Person {
    private Dog dog;
    // 1、构造方法注入
    @Autowired
    public Person(Dog dog) {
        this.dog = dog;
    }
    private Cat cat;
    // 2、Set方法注入
    @Autowired
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    // 3、通过属性注入
    @Autowired
    private Pig pig;
    private List<String> stringList;
    // 4、注入List类型
    @Autowired
    // 指定Bean的ID
    // @Qualifier(value = "stringList")
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }
    public List<String> getStringList() {
        return stringList;
    }
    // 5、Map类型注入
    private Map<String, Integer> stringIntegerMap;
    public Map<String, Integer> getStringIntegerMap() {
        return stringIntegerMap;
    }
    @Autowired
    public void setStringIntegerMap(Map<String, Integer> stringIntegerMap) {
        this.stringIntegerMap = stringIntegerMap;
    }
    private String name;
    // 6、String、Integer等类型直接赋值
    @Value("Tom") // 如果是Integer会自动转型
    public void setName(String name) {
        this.name = name;
    }
    // 7、容器内置接口注入
    private ApplicationContext context;
    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }
    public ApplicationContext getContext() {
        return context;
    }
    @Override
    public String toString() {
        return "Person{" +
                "dog=" + dog +
                ", cat=" + cat +
                ", pig=" + pig +
                ", stringList=" + stringList +
                ", stringIntegerMap=" + stringIntegerMap +
                ", name='" + name + '\'' +
                '}';
    }
}

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        ApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        // 获取Bean
        Person bean = context.getBean("person", Person.class);
        System.out.println(bean);
        System.out.println(bean.getStringList());
        System.out.println(bean.getStringIntegerMap());
        System.out.println(bean.getContext().getBean("cat"));
    }
}

测试输出

Person{dog=com.demo.ioc.Dog@441772e, 
    cat=com.demo.ioc.Cat@7334aada, 
    pig=com.demo.ioc.Pig@1d9b7cce, 
    stringList=[string2, string1], 
    stringIntegerMap={integer1=222, integer2=223}, 
    name='Tom'
}
[string2, string1]
{integer1=222, integer2=223}
com.demo.ioc.Cat@7334aada

通过注解设定Bean的作用域

1、Spring预定义作用域

xml形式

<bean id="bean" class="com.demo.ioc.Person" scope="singleton"/>

注解形式

@Component
@Scope("singleton")  // prototype
public class Person {
}
// 或者
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean
    @Scope("singleton")
    public Person person() {
        return new Person();
    }

2、自定义Scope作用域

回忆之前的自定义Scope代码

package com.demo.ioc;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 自定义作用域
 * 实现双例模式(每一个Bean对应两个实例)
 */
public class MyScope implements Scope {
    Map<String, Object> map1 = new ConcurrentHashMap<>();
    Map<String, Object> map2 = new ConcurrentHashMap<>();
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        //先从map1取
        if (!map1.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map1.put(name, obj);
            return obj;
        }
        //再从map2取
        if (!map2.containsKey(name)) {
            Object obj = objectFactory.getObject();
            map2.put(name, obj);
            return obj;
        }
        // 如果map1和map2中都存在则随机返回
        int i = new Random().nextInt(2);
        if (i == 0) {
            return map1.get(name);
        } else {
            return map2.get(name);
        }
    }
    @Override
    public Object remove(String name) {
        // 和添加顺序正好相反
        if(map2.containsKey(name)){
            Object obj = map2.get(name);
            map2.remove(name);
            return obj;
        }
        if(map1.containsKey(name)){
            Object obj = map1.get(name);
            map1.remove(name);
            return obj;
        }
        return null;
    }
    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
    }
    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }
    @Override
    public String getConversationId() {
        return null;
    }
}

xml形式

<!-- 1、将Scope交由Spring管理 -->
<bean id="myScope" class="com.demo.ioc.MyScope"/>
<!-- 2、配置 -->
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="myScope" value-ref="myScope"/>
        </map>
    </property>
</bean>
<!-- 3、使用 -->
<bean class="com.demo.ioc.Bean" id="bean" scope="myScope"/>

注解形式

package com.demo.ioc;
import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    // 1、交由Spring管理
    @Bean
    public MyScope myScope(){
        return new MyScope();
    }
    // 2、配置
    @Bean
    public CustomScopeConfigurer customScopeConfigurer(){
        CustomScopeConfigurer configurer = new CustomScopeConfigurer();
        configurer.addScope("myScope", myScope());
        return configurer;
    }
    // 3、使用
    @Bean
    @Scope("myScope")
    public Person person() {
        return new Person();
    }
}

测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        ApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        // 获取Bean
        for (int i = 0; i < 10; i++) {
            Person bean = context.getBean("person", Person.class);
            System.out.println(bean);
        }
    }
}

Bean注解的方式进行方法注入

回顾方法注入场景:

Bean1是singleton, Bean2是prototype, Bean1依赖于Bean2

我们希望每次调用Bean1某个方法时候,该方法每次拿到Bean2都是新的实例

package com.demo.ioc;
public class Bean2 {
}
package com.demo.ioc;
public abstract class Bean1 {
    protected abstract Bean2 createBean2();
}

xml方式

<bean id="bean2" class="com.demo.ioc.Bean2" scope="prototype"/>
<bean id="bean1" class="com.demo.ioc.Bean1" scope="singleton">
    <lookup-method name="createBean2" bean="bean2"/>
</bean>

注解形式

package com.demo.ioc;
@Component
@Scope("prototype")
public class Bean2 {
}
package com.demo.ioc;
@Component
public abstract class Bean1 {
    @Lookup
    protected abstract Bean2 createBean2();
}

通过注解开启Bean的懒加载

xml形式

<!-- 单个 -->
<bean class="com.demo.ioc.Bean" id="bean" lazy-init="true"/>
<!-- 全局 -->
<beans default-lazy-init="true"></beans>

注解形式

/**
 * 单个
 */
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean
    @Lazy
    public Person person() {
        return new Person();
    }
}
// 或者
@Component
@Lazy
public class Person {
}
/**
 * 全局
 */
@Configuration
@ComponentScan(value = "com.demo.ioc")
@Lazy
public class MyConfiguration {
    @Bean
    public Person person() {
        return new Person();
    }
}

通过注解编写Bean初始化及销毁

配置文件

package com.demo.ioc;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// 创建配置文件,可以认为是一个xml配置文件
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
}

上下文测试

package com.demo.ioc;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class BeanTest {
    @Test
    public void testBean() {
        // 获取上下文
        AbstractApplicationContext context =
                new AnnotationConfigApplicationContext(MyConfiguration.class);
        Person bean = context.getBean("person", Person.class);
        context.close();
    }
}

方式一:

package com.demo.ioc;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class Person implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("Person.destroy");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Person.afterPropertiesSet");
    }
}

方式二:

package com.demo.ioc;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class Person {
    @PostConstruct
    public void onInit(){
        System.out.println("Person.onInit");
    }
    @PreDestroy
    public void onDestroy(){
        System.out.println("Person.onDestroy");
    }
}

方式三

package com.demo.ioc;
public class Person {
    public void onInit() {
        System.out.println("Person.onInit");
    }
    public void onDestroy() {
        System.out.println("Person.onDestroy");
    }
}


package com.demo.ioc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.demo.ioc")
public class MyConfiguration {
    @Bean(initMethod = "onInit", destroyMethod = "onDestroy")
    public Person person() {
        return new Person();
    }
}


相关文章
|
1天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
15 6
|
22天前
|
前端开发 Java Spring
Spring MVC核心:深入理解@RequestMapping注解
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的核心,它将HTTP请求映射到控制器的处理方法上。本文将深入探讨`@RequestMapping`注解的各个方面,包括其注解的使用方法、如何与Spring MVC的其他组件协同工作,以及在实际开发中的应用案例。
36 4
|
22天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
67 2
|
22天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
40 2
|
25天前
|
消息中间件 Java 数据库
解密Spring Boot:深入理解条件装配与条件注解
Spring Boot中的条件装配与条件注解提供了强大的工具,使得应用程序可以根据不同的条件动态装配Bean,从而实现灵活的配置和管理。通过合理使用这些条件注解,开发者可以根据实际需求动态调整应用的行为,提升代码的可维护性和可扩展性。希望本文能够帮助你深入理解Spring Boot中的条件装配与条件注解,在实际开发中更好地应用这些功能。
31 2
|
26天前
|
JSON Java 数据格式
springboot常用注解
@RestController :修饰类,该控制器会返回Json数据 @RequestMapping(“/path”) :修饰类,该控制器的请求路径 @Autowired : 修饰属性,按照类型进行依赖注入 @PathVariable : 修饰参数,将路径值映射到参数上 @ResponseBody :修饰方法,该方法会返回Json数据 @RequestBody(需要使用Post提交方式) :修饰参数,将Json数据封装到对应参数中 @Controller@Service@Compont: 将类注册到ioc容器
|
22天前
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
57 0
|
2月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
72 1
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
1月前
|
XML Android开发 数据格式
Eclipse 创建 XML 文件
Eclipse 创建 XML 文件
27 2
下一篇
DataWorks