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. 解决shell脚本错误$’r’ command not found

    从windows上传了一个脚本到Linux上执行 出现如下错误:$'\r': command not found这是windows与Unix文本编辑的默认格式不同造成的,需要转成unix格式. 解决方 ...

  2. 【C# 异常处理】 开端

    异常概述 在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是 ...

  3. CLR 详解

    公共语言运行时就是按照CLI标准制作的执行托管代码的环境.CLR 能运行非托管代码. 公共语言运行的功能:代码JIT/AOT编译.  内存管理 .垃圾回收.异常处理.反射服务.安全服务.程序集加载.本 ...

  4. 60天shell脚本计划-6/12-渐入佳境

    --作者:飞翔的小胖猪 --创建时间:2021年2月21日 --修改时间:2021年2月25日 说明 每日上传更新一个shell脚本,周期为60天.如有需求的读者可根据自己实际情况选用合适的脚本,也可 ...

  5. centos7 下配置snort2.9 以及使用

    先安装依赖文件 yum -y install epel-release //需要epel源 yum -y install gcc flex bison zlib zlib-devel libpcap ...

  6. oj教程--排序算法(Java)

    import java.util.ArrayList; import java.util.List; /** * 排序算法主类 * * @author eric */ class SortArray ...

  7. ImageNet2017文件介绍及使用

    ImageNet2017文件介绍及使用 文件说明 imagenet_object_localization.tar.gz包含训练集和验证集的图像数据和地面实况,以及测试集的图像数据. 图像注释以PAS ...

  8. Python:Scrapy(四) 命令行相关

    学习自Scrapy 2.4.1 documentation 这一部分是对官方文档的学习,主要是理解翻译,来对之前的应用部分进行详细的理论补充. 1.保存爬取到的要素的方式: ①运行scrapy指令时, ...

  9. k8s-静态PV和动态PV

    1.pv 简单介绍 PersistenVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理 PV分为静态和动态,动态能够自动创建PV • PersistentVolumeCl ...

  10. VMware虚拟机三种网络模式

    VMware三种网络模式 在学习中经常遇到Vmware虚拟机网络设置有问题,可能是因为你没有理解这三种网络模式的工作原理.VMware虚拟机常见的网络类型有bridged(桥接).NAT(地址转换). ...