java-spring

 

 

 

Spring-IOC

ioc概念

控制反转

把对象创建和对象之间的调用过程,交给Spring 进行管理。

目的就是,为了降低耦合度,因为当你想在一个类当中调用另外一个类的方法,你需要获得另外一个类的实例

 

 

IOC的底层原理:
包括xml解析,工厂模式,反射

 

 

 引入工厂模式之后:

 

 

IOC解耦过程

 

 

IOC接口:

1Ioc思想基于IOC容器完成,IO容器底层就是对象工厂
2Spring提供IOC容器实习两种方式:两个接口

1)BeanFactory :IOC容器基本实现,Spring内部的使用接口,不提供给开发人员进行使用

2)ApplicationContext :BeanFactory接口的子接口,提供更强大的功能,一般开发人员使用


区别:
BeanFactory 加载配置文件的时候不会创建对象,在获取对象的时候才创建。

ApplicationContext ,加载文件的时候,会将配置文件里面的对象进行创建。

获取IOC容器的方式

通过beanFactory

通过applicationContext获取

3 ApplicationContext接口实现类

 

 FileSystemXmlApplicationContext从盘符路径开始查找配置文件,绝对路径

ClassPathXmlApplicationContext项目路径下查找-----一般使用

 

 

IOC操作Bean管理
Bean管理是什么:

1Spring创建对象
2Spring注入属性

Bean管理操作两种方式

基于xml配置文件方式实现
基于注解方式实现

 

JOC操作Bean管理--基于xml方式

基于xml方式创建对象

</bean>
<bean id="usert" class="com.quan.Usert" >
</bean>

1)在sprin配置文件中,使用bean标签,标签理添加相应的属性,就可以实现对象创建

2)bean标签的属性

id:属性 =唯一标识

class属性=类的全路径

 3)默认使用无参构造方法完成对象的创建

bean标签的属性init-method= destroy-method=

 

先说两个接口先:

InitializingBean DisposableBean 标记接口 ,
主要实现Spring 执行bean时的初始化和销毁时某些方法

实现InitializingBean ,需要实现afterPropertiesSet,就是设置所有的属性之后做什么
实现DisposableBean 实现destory(),就是Spring 容器释放该bean之后做些什么

public class InitialDisp implements InitializingBean, DisposableBean {

    public void destroy() throws Exception {
        System.out.println("destroy");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("afterProper");
    }
}

 执行:

public class BETest {
    public static void main(String[] args) {
        /*
        ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable
        ApplicationContext:应用上下文
        Lifecycle:负责context的生命周期进行管理,提供start(),stop() 以及isRunning()
        Closeable:用于关闭组件,释放资源
        ConfigurableApplicationContext 接口的作用就是设置上下文 ID,设置父应用上下文,添加监听器,刷新容器,关闭,判断是否活跃等方法
         */
        ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        InitialDisp id = (InitialDisp)ac.getBean("initdesp");
        System.out.println(id);
        ac.close();
    }
}
/*
re:
afterProper
com.quan.hll.InitialDisp@1f36e637
destroy
 */

但是不建议使用这两个接口

 

可以指定类中的某个方法为两个阶段的方法:init-method= destroy-method=

上面的类不在继承那两个接口

再bean配置文件当中:

 <bean id="initdesp" class="com.quan.hll.InitialDisp" init-method="afterPropertiesSet" destroy-method="destroy"></bean>
建议使用init-method 和 destroy-methodbean 在Bena配置文件,而不是执行 InitializingBean 和 DisposableBean 接口,也会造成不必要的耦合代码在Spring。
 

 设置bean加载和销毁所调用的方法

</bean>
<bean id="usert" class="com.quan.Usert" init-method="init" destroy-method="destroy">
</bean>

test;

      ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");

        Usert usert = (Usert)ac.getBean("usert");
        usert.say();
        //关闭ioc容器
        ((ClassPathXmlApplicationContext) ac).close();

 

 

基于xml方式注入属性

1)DI: 依赖注入,就是注入属性,是IOC的一种实现方式

依赖注入-setter方法;

 11类需要各个属性的set方法

22配置文件中先创建对象,再注入属性

 

 

 

 依赖注入---构造方法

1)需要创建有参构造函数

2)配置文件中使用constructor-arg标签 

第一个类:

View Code

第二个类:

View Code

spring-config.xml配置

<!--    创建User对象,id是这个资源的唯一表示-->
<bean id="user" scope="prototype" class="com.quan.User">
<!--    通过构造方法注入-->
    <constructor-arg index="0" value="QQgou"/>
    <constructor-arg index="1" ref="usert"/>
<!--    这里的user实例里面的name属性会被下面的设置替代,如果没有就是构造器的值-->
    <property name="name">
        <value>QQSpring</value>
    </property>
<!--  name这里是指User类里面的属性usert  这里的ref是指下面的bean-->
    <property name="usert" ref="usert">
    </property>
</bean>
<bean id="usert" class="com.quan.Usert" init-method="init" destroy-method="destroy">
</bean>

re;

init see you
how to sayQQSpring
see you

注:加颜色就是通过构造方法注入的形式,里面还有属性是其他类的设置

 

 

 

 

IOC操作Bean管理-xml注入其他类型属性

 字面量

 null值

 再熟悉值里面不要设置value属性,直接加入null标签

    <bean id="user" class="com.quan.hlll.User">
        <property name="name">
            <null></null>
        </property>
    </bean>

特殊符号<<>>

进行转义操作

    <bean id="user" class="com.quan.hlll.User">
        <property name="name" value="&lt;&gt;<<南京>>"></property>
    </bean>

 

 

 

把带特殊符号内容写到CDATA

    <property name="name">
            <value><![CDATA[<<南京>>]]></value>
        </property>

注入属性-外部bean

person累有一个属性为hello对象类型

     <bean id="person" class="com.quan.hll.javaConfig.Person.Person">
          <constructor-arg index="0" value="QQQ"/>
          <constructor-arg index="1" ref="hello" />
     </bean>
     <bean id="hello" class="com.quan.hll.javaConfig.Hello.Hello"></bean>

 

 

注意属性-内部bean和级联赋值

 

View Code

 

通过构造函数(其实set方法也是可以的)

     <bean id="person" class="com.quan.hll.javaConfig.Person.Person">
          <constructor-arg index="0" value="QQQ"/>
          <constructor-arg index="1" >
               <bean class="com.quan.hll.javaConfig.Hello.Hello"></bean>
          </constructor-arg>
     </bean>

 

 

 

 

 内部定义的累有属性的时候

注意:建议在类的内部进行内部类的定义:

 <bean id="person" class="com.quan.hll.javaConfig.Person.Person">
          <constructor-arg index="0" value="QQQ"/>
          <constructor-arg index="1" >
              <bean class="com.quan.hll.javaConfig.Hello.Hello">
                   <property name="msg">
                        <value>ourmsg</value>
                   </property>
              </bean>
          </constructor-arg>
     </bean>

 

 

bean属性值的注入两种xml格式

View Code

 

<!--     使用属性标签property其的下级value属性进行值的注入,-->
     <bean id="mconstructor" class="com.quan.hll.manyConstruntor.MConstructor" >
          <property name="name" >
               <value>quan</value>
          </property>
          <property name="addr">
               <value>gd</value>
          </property>
          <property name="age">
               <value>23</value>
          </property>
     </bean>

 

<!--     使用快捷方式进行值的注入,-->
     <bean id="mconstructor" class="com.quan.hll.manyConstruntor.MConstructor" >
          <property name="age" value="23"/>
          <property name="addr" value="gd"/>
          <property name="name" value="q1234"/>
     </bean>

 

IOC操作Bean管理(xml-注入集合属性)

 

格式:

<list value-type="java.lang.String">
    <value>list里面的元素</value>
        ...
</list>

<set>
    <value>set元素</value>
            ...
</set>


<map>
    <entry key=key值 value=key值对应的value/>
    ....
</map>


<props>
    <prop key=key值>value值写这里</prop>
            .....
</props>

 

 

eg

<bean id="springlist" class="com.quan.hll.List.SpringList">
<!--          list-->
          <property name="lists" >
               <list value-type="java.lang.String">
                    <value>quan</value>
                    <value>quan</value>
                    <value>quan2</value>
               </list>
          </property>
<!--          set-->
          <property name="sets">
               <set>
<!--                    因为set属性不允许重复,只保留一个-->
                    <value>quan</value>
                    <value>quan</value>
                    <value>quan2</value>
               </set>
          </property>
<!--          Map-->
          <property name="maps">
               <map>
<!--                    同样只保留后者-->
                    <entry key="one" value="QQQ"/>
                    <entry key="one" value="ZZZ"/>
                    <entry key="two" value="ZZZ"/>
               </map>
          </property>
<!--          properties-->
          <property name="properties">
               <props>
                    <prop key="quan">shige213</prop>
                    <prop key="zhi">shige321</prop>
               </props>
          </property>
     </bean>
View Code

 

类:

 

package com.quan.hll.List;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class SpringList {
    private List<Object> lists;
    private Set<Object> sets;
    private Map<Object,Object> maps;
    private Properties  properties;

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Set<Object> getSets() {
        return sets;
    }

    public void setSets(Set<Object> sets) {
        this.sets = sets;
    }

    public Map<Object, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<Object, Object> maps) {
        this.maps = maps;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

 

打印类:

[quan, quan, quan2]
{one=ZZZ, two=ZZZ}
{quan=shige213, zhi=shige321}
[quan, quan2]

 

 

 

 

 

 

 集合里面设置对象

 

 

 

 把集合注入部分提取出来

 

 

 

    <util:list id="publiclist" >
        <value>quan</value>
        <value>QQQ</value>
    </util:list>
    <bean class="com.quan.hll.List.SpringList" id="springList">
        <property name="lists" ref="publiclist"/>
    </bean>

 

IOC操作Bean管理(FactoryBean)

Spring 有两类型bean,一种就是我们一直自己设置的普通bean,另一种就是工厂bean

普通bean ,再配置文件中定义bean类型究竟是返回类型
工厂bean,再配置文件地暖管一bean类型可以和而返回值不一样

工厂bean的理解与实现

1创建一个累,累作为工厂bean,实现接口FactoryBean

2实现接口里面的方法,再实现方法中定义返回的bean类型

public class Mybean implements FactoryBean {
    //返回bean类型
    @Override
    public Object getObject() throws Exception {
        return null;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

这几个方法是可以自定义的,将Object类型改变为其他类型,救可以实现不同返回不同类型了

 

 

 

 

IOC操作Bean管理(bean的作用域)

bean的作用域:再Spring中,设置创建bean实例时单实例还是多实例

默认是单例 
单例 - 每个Spring IoC 容器返回一个bean实例 singleton
原型- 当每次请求时返回一个新的bean实例 prototype
请求 - 返回每个HTTP请求的一个Bean实例
会话 - 返回每个HTTP会话的一个bean实例
全局会话- 返回全局HTTP会话的一个bean实例 

 再spring当中bean标签里面有属性scope,用于设置单实例还是多实例

 

     ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        for (int i = 0; i < 3; i++) {
            User user = (User)ac.getBean("user");
            System.out.println(user);
        }

 singleton作用域

共享一个实例bean,只创建一个实例,同一个地址

  <bean id="user" class="com.quan.hlll.User" scope="singleton"/>

 结果为:

/*socpe为sigleon的时候
com.quan.User@67784306
com.quan.User@67784306
com.quan.User@67784306
 */

prototype作用域

每次注入这个类的时候,都创建一个实例

<bean id="user" class="com.quan.hlll.User" scope="prototype"/>

结果:

v/*socpe为prototype的时候
com.quan.User@63753b6d
com.quan.User@6b09bb57
com.quan.User@6536e911
 */

sigleton 和prototype的区别:

singleton时,加载spring配置文件时候就会创建单实例对象
prototype的时候,不是再加载spring配置文件时候创建对象,再调用getBean方法时候i创建多时了对象

 

IOC操作Bean管理(bean生命周期)

生命周期:从对象创建到对象销毁的过程

bean的生命周期

1通过构造器创建bean实例(无参构造)
22为bean的属性设置值和对其他bean的引用(调用set方法)
33调用bean的初始化的方法(需要进行配置初始化的方法)
44bean可以使用
55当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

 

public class User {
    public User(){
        System.out.println("第一步");
    }

    public String name;

    public void setName(String name) {
        this.name = name;
        System.out.println("第二部");
    }

    public void initMethod(){
        System.out.println("第三步");
    }

    public void destroy(){
        System.out.println("第五步");
    }
}

配置文件

    <bean id="user" class="com.quan.hlll.User"  init-method="initMethod" destroy-method="destroy"/>
public class Main {
    public static void main(String[] args) {
        //加载配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        User user = ac.getBean("user",User.class);
        System.out.println("第四步");
        System.out.println(user);

        //手动让bean实例销毁,即关闭IOC容器
        ((ClassPathXmlApplicationContext)ac).close();
    }
}

 

 

 

bean的后置处理器

 

 

 

一旦你实现了BeanPostProcessoer接口且将该处理器bean配置到配置文件中,那所有的bean都会
自动调用这个累实现的方法

有后置处理器之后的生命周期

(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法) (
3)把bean实例传递bean后置处理器的方法postProcessBeforeInitialization4)调用bean的初始化的方法(需要进行配置初始化的方法) 5)把bean实例传递bean后置处理器的方法 postProcessAfterInitialization6)bean可以使用了(对象获取到了) (7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

 

IOC操作Bean管理(xml自动装配)少用

我们之前都是通过标签,标签属性,各种子标签去实现bean的创建,这种事手动装配

自动装配:

根据指定装配规则(属性名称或者属性类型),Spring自动将配置的属性值进行注入

 

主要使用 bean里面的autwire属性进行实现

 

 

 

使用byType,如果IOC容器当中存在多个同类型的Bean就会出现错误

 

IOC操作Bean管理(引入外部属性文件)

应用场景

我们将一些固定的值写道变量配置文件当中
以后如果需要该的时候,我们不需要去动配置文件
只需要进行属性变量配置文件中就行

例如我们数据库源的配置就可以写到里面

使用 PropertyPlaceholderConfigurer映射

用于配置文件的管理,

 

datasource.properties

driver=com.jdbc.mysql.connection
url=jdbc:mysql:localhost:3306
username=root
password=2009

把外部文件引入到Spring配置文件当中去 

111加入名称空间

       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">

222通过context:property-plavehodeer 标签引入外部属性文件

<context:property-placeholder location="datasource.properties"/>
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
         <property name="driverClassName" value="${driver}"/>
         <property name="username" value="${username}"/>
         <property name="password" value="${password}"/>
         <property name="url" value="${url}"/>
     </bean>

 下面事直接配置(不对应,莫怪)下面事加载德鲁伊的连接池

 

 

 

IOC操作Bean管理(基于注解方式)

1、什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化xml配置

 

2、Spring针对Bean管理中创建对象提供注解1)@Component
(2)@Service
(3)@Controller
(4)@Repository
* 上面四个注解功能是一样的,都可以用来创建bean实例

他们只是有 一些默认规则而已:

 

基于注解方式实现对象的创建

111要引入aop依赖

222开启组件自动扫描

加入context名称空间

 

 

 33配置扫描路径

 <context:component-scan base-package="com.quan.hll"/>

扫描多个包的时候,可以使用逗号隔开:

<context:component-scan base-package="com.quan.hll,com.quan.li"/>

或者直接换成更大的范围

<context:component-scan base-package="com.quan"/>

 

44累并添加注解

@Component("outpute")
public class OutputE  {
    @Value("ouputeName")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void pr() {
        System.out.println("EEEEEEEEEEEEEEEEeeeeee");
    }
}



@Component("hou")
public class HOutputE {
    @Autowired
    private OutputE outpute;

    public OutputE getOutpute() {
        return outpute;
    }
}

 

开启组件自动扫描的细节问题

如果我们只是配置下面这个配置文件,spring会将这个路径下的所有累进行扫描一遍

<context:component-scan base-package="com.quan"/>

 

自动扫描的过滤器

<!--
use-default-filters="false" 不适用默认的过滤器
 <context:include-filter  定义需要加入扫描的东西
 下面就是只扫描类存在注解为Controller
-->
    <context:component-scan base-package="com.quan.hll" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

<!--    处理类的注解为Controller不扫描,其他都要扫描-->
    <context:component-scan base-package="com.quan.hll" use-default-filters="false">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

 

基于注解方式实现属性的注入

针对类类型的:

(1)@Autowired:根据属性类型进行自动装配

@Repository
public class DaoImpl  implements Dao {
    @Override
    public void add() {
        System.out.println("dao add");
    }
}

service 层

@Service(value = "dService")
public class DService {
    //不需要假set方法
    @Autowired
    private Dao dao;

    public void add(){
        System.out.println("service add...");
        dao.add();
    }
}

test:

public class Main {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        DService dService = ac.getBean("dService",DService.class);
        dService.add();
    }
}

结果输出为:

service add...
dao add

 

(2)@Qualifier:根据名称进行注入
这个@Qualifier注解的使用,和上面@Autowired一起使用

因为我们一个接口可能存在多个实现它的类所以这时候我们只是用Autowired来指定是不够的

需要指定bean的名字去注入

@Service(value = "dService")
public class DService {
    //不需要假set方法
    @Autowired
    @Qualifier(value = "daoImpl")
    private Dao dao;
    public void add(){
        System.out.println("service add...");
        dao.add();
    }
}

 

(3)@Resource:可以根据类型注入,也可以根据名称注入

@Service(value = "dService")
public class DService {
//    @Resource 什么都不加的时候根据类型注入
    @Resource(name = "daoImpl")
    private Dao dao;
    public void add(){
        System.out.println("service add...");
        dao.add();
    }
}

注意:Resource注解是在import javax.annotation.Resource;就是java扩展包里面的,这个是java的

而@Autowired是在org.springframework.beans.factory.annotation.Autowired;spring内部的

建议使用@Autowired

 

(4)@Value 注入基本的类型

  @Value("quan")
    private String name;

    @Value("34")
    private int age;

 

完全注解开发

是指用配置类去替代配置文件bean.xml

@Configuration //作为配置类,替代xml配置文件

建立类,并使用注解成为配置类:

@Configuration
@ComponentScan(basePackages = {"com.quan.hlll"})
public class SpringConfig {
}

加载配置的方式变了,变成了注释方式加载

public class Main {
    public static void main(String[] args) {
        //通过配置类加载
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        DService dService  = ac.getBean("dService",DService.class);
        dService.add();
    }
}

其实这个是Spring-boot里面的内容了,

 

???????

/*
通过java类来加载bean,注解
 */

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HelloConfig {
    @Bean(name = "hello")
    public Hello hello(){
        return new Hello();
    }
}

相当于:

 <bean id="hello" class="com.quan.hll.javaConfig.Hello" ></bean>

 

        //通过JavaConfig的类对象来获取ApplicationConext
//        ApplicationContext ac = new AnnotationConfigApplicationContext(HelloConfig.class);
        //通过spring-config.xml配置文件来进行bean加载
        ApplicationContext ac =  new ClassPathXmlApplicationContext("spring-config.xml");

 

 

 

 

 

 

 

 

 

 

 

spring注入日期:

     <bean id="sdate" class="com.quan.hll.List.Sdate">
<!--          使用下面会报错,必须使用格式话进行格式话-->
<!--          <property name="date" value="2020-12-20"/>-->
<!--          Cannot convert value of type [java.lang.String] to required type -->
<!--          [java.util.Date] for property 'date': no matching edit-->
               <property name="date">
                    <bean factory-bean="dataFormat" factory-method="parse">
                         <constructor-arg value="2020-12-20"></constructor-arg>
                    </bean>
               </property>
     </bean>

     <bean id="dataFormat" class="java.text.SimpleDateFormat">
          <constructor-arg value="yyyy-MM-dd"/>
     </bean>

 

re:Sdate{date=Sun Dec 20 00:00:00 CST 2020}

 

 

 

 

spring-bean的继承

这里不是在java下创建类去extend而是通过bean的配置文件去实现

主要是bean父设置一个模板或者属性,子bean公用这个属性或者模板

 

类:

public class BasePlace  {
    private String place;
    private String name;

 

下面父bean只是共享自己的name的属性值

    <bean id="base" class="com.quan.hll.expand.BasePlace" >
        <property name="name" value="Q"/>
    </bean>

    <bean id="expandbase" parent="base">
        <property name="place" value="sz"/>

    </bean>

注意:其实expandbase这个bean也是com.quan.hll.expand.BasePlace类

 

加入下面的这个bean标签的属性是说明父bean不可被实例化:

 <bean id="base" class="com.quan.hll.expand.BasePlace" abstract="true">

如果调用:
BasePlace bb = (BasePlace)ac.getBean("base");

报错

 

加入下面一句,子类bean新设置的属性值会覆盖父bean

 <property name="name" value="QQ"/>

BasePlace{place='sz', name='Q'}

 

 

 

 

@Required注解依赖检查,指定类中的属性检查,部分!!!

单单加入这个还是不生效,需要在bean.xml文件里面引入解析注解的bean

适用于bean属性setter方法,并表示受影响的bean属性必须在XML配置文件在配置时进行填充。否则,容器会抛出一个BeanInitializationException异常。

 

public class BasePlace  {
    private String place;
    private String name;


    @Required
    public void setName(String name) {
        this.name = name;
    }

bean。xml

    <bean id="base" class="com.quan.hll.expand.BasePlace" >
        <property name="place" value="ShenZhen"/>
    </bean>

 

baocuo

org.springframework.beans.factory.BeanInitializationException:
 Property 'name' is required for bean 'base'

 

注册一个RequiredAnnotationBeanPostProcessor以了解在bean配置文件@Required注解

111

设置context:

<context:annotation-config/>

22设置bean

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

 

 

自定义@required注解名字(换名字)

编写注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyRequired {
}

 

注册注解:

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
    <property name="requiredAnnotationType" value="com.quan.hll.MyRequired"></property>
</bean>

 

使用即可:

public class BasePlace  {
    private String place;
    private String name;


    @MyRequired
    public void setName(String name) {
        this.name = name;
    }

 

 

 

 

 

 

 

 

 

 

多个bean模块化设置配置文件

 

 

 

 

 

 

 

多个构造函数的歧义

package com.quan.hll.manyConstruntor;

public class MConstructor{
    private  String name;
    private int age;
    private String addr;

    /*
    两个构造函数,可能会出现起义
     */
    public MConstructor(int age, String name,  String addr) {
        this.name = name;
        this.age = age;
        this.addr = addr;
    }

    public MConstructor(String name, int age, String addr) {
        this.name = name;
        this.age = age;
        this.addr = addr;
    }


    @Override
    public String toString() {
        return "MConstructor{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}

/*
第一次没有指定类型出现这个结果:
MConstructor{name='23', age=199, addr='123'}
 */

 

<!--     两个构造函数,可能会出现起义-->
<!--     <bean id="mconstructor" class="com.quan.hll.manyConstruntor.MConstructor" >-->
<!--          <constructor-arg >-->
<!--               <value>199</value>-->
<!--          </constructor-arg>-->
<!--          <constructor-arg>-->
<!--               <value>23</value>-->
<!--          </constructor-arg>-->
<!--          <constructor-arg>-->
<!--               <value>123</value>-->
<!--          </constructor-arg>-->
<!--     </bean>-->

<!--     为构造函数指定的确切数据类型,-->
     <bean id="mconstructor" class="com.quan.hll.manyConstruntor.MConstructor" >
          <constructor-arg type="java.lang.String" >
               <value>199</value>
          </constructor-arg>
          <constructor-arg type="int">
               <value>23</value>
          </constructor-arg>
          <constructor-arg type="java.lang.String">
               <value>123</value>
          </constructor-arg>
     </bean>

 

 

 

多个配置文件归结到一个配置文件

 

     <import resource="hello-config.xml"/>
     <import resource="person-config.xml"/>

 

 

 

 


SpEL(Spring Expression Language),

 

posted @ 2020-07-04 15:18  小丑quan  阅读(263)  评论(0)    收藏  举报