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标签

第一个类:

第二个类:

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和级联赋值

通过构造函数(其实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格式

<!--     使用属性标签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>

类:

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后置处理器的方法postProcessBeforeInitialization
(4)调用bean的初始化的方法(需要进行配置初始化的方法)
(5)把bean实例传递bean后置处理器的方法 postProcessAfterInitialization
(6)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),

java-spring的更多相关文章

  1. 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)

    Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...

  2. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  3. 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)

    硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...

  4. 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)

    从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...

  5. 从零开始学 Java - Spring 支持 CORS 请求踩的坑

    谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...

  6. 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求

    论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...

  7. 从零开始学 Java - Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...

  8. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  9. 支持Java Spring MVC

    Java Spring MVC能很方便在后台返回JSON数据,所以与MiniUI进行数据交互非常简单. 1)后台处理: 在MVC控制器中,可以通过方法参数接收数据,也可以通过Request接收更复杂的 ...

  10. Java Spring AOP用法

    Java Spring AOP用法 Spring AOP Java web 环境搭建 Java web 项目搭建 Java Spring IOC用法 spring提供了两个核心功能,一个是IoC(控制 ...

随机推荐

  1. k8s核心资源之:名称空间(ns)

    简介 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或者用户组. 常见的pod.service.replicaSet和deployment等都是属于某一个namespac ...

  2. Renix中如何实现流调速——网络测试仪实操

    在Renix操作中有时我们需要进行流调速,那么如何实现呢?接下来为您详细介绍. 第一步:预约测试资源 首先打开Renix软件,连接机箱, 预约端口 第二步:流调速 例如:端口下有3条流,分别设置为10 ...

  3. excel制作折线图太麻烦?试试这些折线图在线生成工具

    折线图是以折线的上升或下降来表示统计数量的增减变化的统计图,叫作折线统计图.用折线的起伏表示数据的增减变化情况,不仅可以表示数量的多少,而且可以反映数据的增减变化情况.并且折线图也是目前最方便的一种统 ...

  4. 思迈特软件Smartbi发展再提速,完成B+轮过亿战略融资

    2021年4月,思迈特软件(Smartbi)宣布完成亿级B+轮战略融资,本轮投资方为领先的全球企业级数据分析和组织智能服务平台提供商--明略科技.此前,思迈特软件曾先后获得来自价值资本.方广资本的数千 ...

  5. Django ORM 多表操作

    目录 Django ORM 多表操作 表模型 表关系 创建模型 逆向到表模型 插入数据 ORM 添加数据(添加外键) 一对多(外键 ForeignKey) 一对一 (OneToOneFeild) 多对 ...

  6. ASP.NET Core 6框架揭秘实例演示[14]:日志的进阶用法

    为了对各种日志框架进行整合,微软创建了一个用来提供统一的日志编程模式的日志框架.<日志的基本编程模式>以实例演示的方式介绍了日志的基本编程模式,现在我们来补充几种"进阶" ...

  7. 【C#设计模式】里氏替换原则

    今天,我们再来学习 SOLID 中的"L"对应的原则:里式替换原则. 里氏替换原则 里氏替换原则(Liskov Substitution Principle):派生类(子类)对象能 ...

  8. 十分钟掌握CSS基本内容

         (一) 定位      绝对定位和相对定位.其实用一句话说就是"子绝父相",理解这句话很多效果通过定位做出来的话都没问题了.一般平时用的都的情况都是子div设置为绝对定位 ...

  9. Oracle数据库常用命令整理

    转至:https://blog.csdn.net/creativemobile/article/details/8982164 1监听 (1)启动监听 lsnrctl start (2)停止监听  l ...

  10. selenium+python自动化102-登录页面滑动解锁(ActionChains)

    前言 登录页面会遇到滑动解锁,滑动解锁的目的就是为了防止别人用代码登录(也就是为了防止你自动化登录),有些滑动解锁是需要去拼图这种会难一点. 有些直接拖到最最右侧就可以了,本篇讲下使用 seleniu ...