目录
6.集合属性,List,Map,Set,Properties,数组
20.JdbcTemplate, JdbcDaoSupport 示例代码,具名参数
1.Spring的概念
创建时间: | 2018/7/17 20:49 |
更新时间: | 2018/7/18 11:26 |
作者: | 1876333166@qq.com |
-
Spring 是一个开源框架.
-
Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.
-
Spring 是一个 IOC(DI) 和 AOP 容器框架.
-
具体描述 Spring:
-
轻量级:Spring 是非侵入性的 - 基于 Spring 开发的应用中的对象可以不依赖于 Spring 的 API
-
依赖注入(DI --- dependency injection、IOC)
-
面向切面编程(AOP --- aspect oriented programming)
-
容器: Spring 是一个容器, 因为它包含并且管理应用对象的生命周期
-
框架: Spring 实现了使用简单的组件配置组合成一个复杂的应用. 在 Spring 中可以使用 XML 和 Java 注解组合这些对象
-
一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库 (实际上 Spring 自身也提供了展现层的 SpringMVC 和 持久层的 Spring JDBC)
-
第一步:下载 springsource-tool-suite-3.4.0.RELEASE-e4.3.1-updatesite.zip 插件
第二步 :安装插件
打开Eclipse ------> Help -----> Install New Software ----->add ---->Archive ----->找到下载的插件打开勾选IDE结尾的选项 ----> Click Next and then Finish
----->Restart eclipse when that is asked
第三步:检查插件是否安装成功
打开Eclipse ---->File ----> New -----> Other 搜索Spring如果有说明成功
2.Spring项目环境搭建
创建时间: | 2018/7/18 8:53 |
更新时间: | 2018/8/3 10:36 |
作者: | 1876333166@qq.com |
第一步:创建一个Web项目,把spring的jar导入到lib目录下面
需要导入的jar:
-
commons-logging-1.1.3.jar
-
spring-beans-4.3.0.RELEASE.jar
-
spring-context-4.3.0.RELEASE.jar
-
spring-core-4.3.0.RELEASE.jar
-
spring-expression-4.3.0.RELEASE.jar
第二步:创建一个实体类如下:给上set,get,构造方法,toString方法(方便查看结果)
package com.yirong.bean;
public class Person {
private int price;
private String book;
}
第三步:创建spring的配置文件 在需要放配置文件的目录下鼠标右键----> New ----> Other ----> 搜索Spring ------> 找到Spring Bean Configuration File ----> Next ---- > 输入配置文件的名字后缀是.xml -----> Next 勾选beans -----> Next ----- > Finish----->文件创建成功
第四步:为第二步实体类配置bean(一个bean就是一个容器) 结构如下
<?xml version="1.0" encoding="UTF-8"?>
<!-- 文件的命名空间,不要修改 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通过全类名方式配置Bean id:自己设定,最好为实体类的小写 class:实体类的全路径-->
<bean id="name" class="com.yirong.bean.Person">
<!-- name:填入的参数是实体类的属性 value:需要给属性赋的值 -->
<property name="price" value="200"></property>
<property name="book" value="编程设计思想"></property>
</bean>
</beans>
第五步:写测试类,测试实体类属性是否赋值成功
package com.yirong.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yirong.bean.Person;
public class Test {
public static void main(String[] args) {
//不使用spring,给Person实体类赋值,方法
Person person = new Person(); //获取实体类对象
person.setBook("编程思想设计"); //通过set方法给属性赋值
person.setPrice(1000);
System.out.println(person); //打印实体类结果
//使用spring方法给属性赋值
//1.创建spring的Ioc容器 spring容器xml文件名字
ClassPathXmlApplicationContext x = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从bean的容器中获取bean的实例
Person person2 = (Person) x.getBean("person");
//3.打印实体类结果
System.out.println(person2);
}
}
3.Spring 中的 Bean 配置
创建时间: | 2018/7/18 10:01 |
更新时间: | 2018/7/18 11:26 |
作者: | 1876333166@qq.com |
-
IOC(Inversion of Control):其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式
-
DI(Dependency Injection) — IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接
-
配置 bean
-
配置形式:基于 XML 文件的方式;
-
Bean 的配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean
-
IOC 容器 BeanFactory & ApplicationContext 概述
-
依赖注入的方式:属性注入;构造器注入
-
注入属性值细节<![CDATA[</>]]>
-
-
在 xml 文件中通过 bean 节点来配置 bean
-
id:Bean 的名称。
-
在 IOC 容器中必须是唯一的
-
若 id 没有指定,Spring 自动将权限定性类名作为 Bean 的名字
-
id 可以指定多个名字,名字之间可用逗号、分号、或空格分隔
-
-
在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.
-
Spring 提供了两种类型的 IOC 容器实现.
-
BeanFactory: IOC 容器的基本实现.
-
ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口.
-
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory
-
无论使用何种方式, 配置文件时相同的.
-
-
ApplicationContext 的主要实现类:
-
ClassPathXmlApplicationContext:从 类路径下加载配置文件
-
FileSystemXmlApplicationContext: 从文件系统中加载配置文件
-
-
ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力
-
ApplicationContext 在初始化上下文时就实例化所有单例的 Bean。
-
WebApplicationContext 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作
4.依赖注入的方法
创建时间: | 2018/7/18 10:25 |
更新时间: | 2018/7/18 14:12 |
作者: | 1876333166@qq.com |
第一种:属性注入,如下:
-
属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象
-
属性注入使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值
-
属性注入是实际应用中最常用的注入方式
<bean id="person" class="com.yirong.bean.Person">
<!-- name:填入的参数是实体类的属性 value:需要给属性赋的值 -->
<property name="price" value="200"></property>
<property name="book" value="编程设计思想"></property>
</bean>
第二种:构造器注入,如下:
-
通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。
-
构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性
<!-- 使用构造方法注入属性 -->
<bean id="person" class="com.yirong.bean.Person">
<!--
使用参数的类型匹配属性可以,区分重载的构造器
type:类型匹配
index:下标匹配
name:名字
-->
<!-- 使用参数的类型匹配属性可以,区分重载的构造器 -->
<constructor-arg value="200" type="int"></constructor-arg>
<constructor-arg value="java开发" type="String"></constructor-arg>
</bean>
public Person(int price, String book) {
super();
this.price = price;
this.book = book;
}
字面值:
-
字面值:可用字符串表示的值,可以通过 <value> 元素标签或 value 属性进行注入。
-
基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式
-
若字面值中包含特殊字符,可以使用 <![CDATA[]]> 把字面值包裹起来。
引用其它 Bean ,给set,get方法,构造方法
-
组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能. 要使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用
-
在 Bean 的配置文件中, 可以通过 <ref> 元素或 ref 属性为 Bean 的属性或构造器参数指定对 Bean 的引用.
-
也可以在属性或构造器里包含 Bean 的声明, 这样的 Bean 称为内部 Bean
下面的Car是一个实体类类型
第一个实体类
package com.yirong.bean;
public class Person {
private int price;
private String book;
private Car car; //引用下一个实体类
}
第二个实体类
package com.yirong.bean;
public class Car {
private String speed;
private int price;
}
Spring配置文件配置
<!-- 配置Person实体类的bean -->
<bean id="person" class="com.yirong.bean.Person">
<!-- 为car属性赋值 因为car属性是bean实体类的类型可以使用ref指向容器中的其他bean-->
<property name="car" ref="car"></property>
</bean>
<!-- 配置Car实体类的bean -->
<bean id="car" class="com.yirong.bean.Car">
<property name="speed" value="200"></property>
<property name="price" value="200"></property>
</bean>
5.内部 Bean与级联属性
创建时间: | 2018/7/18 14:12 |
更新时间: | 2018/7/18 14:13 |
作者: | 1876333166@qq.com |
内部 Bean
-
当 Bean 实例仅仅给一个特定的属性使用时, 可以将其声明为内部 Bean. 内部 Bean 声明直接包含在 <property> 或 <constructor-arg> 元素里, 不需要设置任何 id 或 name 属性
-
内部 Bean 不能使用在任何其他地方
<!-- 配置Person实体类的bean -->
<bean id="person" class="com.yirong.bean.Person">
<!-- 使用内部bean给属性car赋值 -->
<property name="car">
<!-- 配置Car实体类的bean -->
<bean id="car" class="com.yirong.bean.Car">
<property name="speed" value="200"></property>
<property name="price" value="200"></property>
</bean>
</property>
</bean>
级联属性:Spring 支持级联属性的配置
<!-- 配置Person的bean -->
<bean id="person" class="com.yirong.bean.Person">
<constructor-arg value="100" index="0"></constructor-arg>
<constructor-arg value="java开发" index="1"></constructor-arg>
<constructor-arg ref="car"></constructor-arg>
<!-- 给Car属性中speed的属性赋值 -->
<property name="car.speed" value="100"></property>
</bean>
<bean id="car" class="com.yirong.bean.Car"></bean>
6.集合属性,List,Map,Set,Properties,数组
创建时间: | 2018/7/18 14:13 |
更新时间: | 2018/7/19 10:42 |
作者: | 1876333166@qq.com |
集合属性,List
第一步创建实体类:为实体类给上set,get,构造toString,方法
package com.yirong.bean;
import java.util.List;
public class Person {
//创建List集合属性,类型是String类型
private List<String> list;
}
第二步编写spring的配置文件,编写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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="person" class="com.yirong.bean.Person">
<property name="list">
<!-- 向集合中添加数据 类型是实体类规定的类型-->
<list>
<value>java开发</value>
<value>编程设计思想</value>
</list>
</property>
</bean>
</beans>
第三步写测试类,打印实体类集合属性是否有值
public static void main(String[] args) {
//创建 Spring 的 IOC 容器
ApplicationContext x = new ClassPathXmlApplicationContext("applicatContext2.xml");
Person person = (Person) x.getBean("person"); //person是配置文件中bean的id
System.out.println(person);
}
集合属性,Map
-
java.util.Map 通过 <map> 标签定义, <map> 标签里可以使用多个 <entry> 作为子标签. 每个条目包含一个键和一个值.
-
必须在 <key> 标签里定义键
-
因为键和值的类型没有限制, 所以可以自由地为它们指定 <value>, <ref>, <bean> 或 <null> 元素.
-
可以将 Map 的键和值作为 <entry> 的属性定义: 简单常量使用 key 和 value 来定义; Bean 引用通过 key-ref 和 value-ref 属性定义
第一步创建实体类:为实体类给上set,get,构造toString,方法
package com.yirong.bean;
import java.util.Map;
public class Person<T> {
//创建map集合属性
private Map<T, T> map; //map是定义的属性名字,T代表泛型
}
第二步编写spring的配置文件,编写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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.yirong.bean.Person">
<property name="map"> <!-- map是实体类中的属性 -->
<!-- 向集合中添加数据 类型是实体类规定的类型-->
<map>
<entry key="键值对key1" value="value值1"></entry>
<entry key="键值对key2" value="value值2"></entry>
</map>
</property>
</bean>
</beans>
第三步写测试类,打印实体类集合属性是否有值
public static void main(String[] args) {
//使用spring方法给属性赋值
//1.创建spring的Ioc容器 spring容器xml文件名字
ClassPathXmlApplicationContext x = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从bean的容器中获取bean的实例
Person person2 = (Person) x.getBean("person"); //person是配置文件中bean的id
//3.打印实体类结果
System.out.println(person2);
}
集合属性,Set
第一步创建实体类:为实体类给上set,get,构造toString,方法
package com.yirong.bean;
import java.util.Set;
public class Person {
//编写set属性
private Set<String> set;
}
第二步编写spring的配置文件,编写bean,与list方法类似,格式如下:
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置Person的bean -->
<bean id="person" class="com.yirong.bean2.Person">
<property name="set">
<!-- 给set添加数据 -->
<set>
<!-- 直接赋值 -->
<value>今天星期四</value>
<value>今天星期一</value>
<value>今天星期二</value>
<value>今天星期五</value>
</set>
</property>
</bean>
</beans>
第三步写测试类,打印实体类集合属性是否有值,同list方法一样
集合属性,Properties
-
使用 <props> 定义 java.util.Properties, 该标签使用多个 <prop> 作为子标签. 每个 <prop> 标签必须定义 key 属性.
第一步创建实体类:为实体类给上set,get,构造toString,方法
package com.yirong.bean;
import java.util.Properties;
import java.util.Set;
public class Person {
//定义properties属性
private Properties properties;
}
第二步编写spring的配置文件,编写bean,与list方法类似,格式如下:
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置Person的bean -->
<bean id="person" class="com.yirong.bean2.Person">
<!-- 给properties属性赋值 -->
<property name="properties">
<!-- prop中必须定义key属性 -->
<props>
<prop key="user">root</prop>
<prop key="password">root</prop>
<prop key="url">jdbc:mysql://127.0.0.1:3306/test</prop>
<prop key="driver">org.gjt.mm.mysql.Driver</prop>
</props>
</property>
</bean>
</beans>
第三步写测试类,打印实体类集合属性是否有值,同上
集合属性,数组
第一步定义一个实体类,定义一个数组属性
private String[] arr;
第二步编写spring的配置文件,编写bean,与list方法类似,格式如下:
<!-- 配置Person的bean -->
<bean id="person" class="com.yirong.bean2.Person">
<!-- 给properties属性赋值 -->
<property name="arr">
<array>
<value>星期一</value>
<value>星期二</value>
<value>星期三</value>
<value>星期六</value>
</array>
</property>
</bean>
第三步测试
//1.创建spring的Ioc容器 spring容器xml文件名字
ClassPathXmlApplicationContext x = new ClassPathXmlApplicationContext("application.xml");
//2.从bean的容器中获取bean的实例
Person person2 = (Person) x.getBean("person");
//3.打印实体类结果
System.out.println(person2);
7.使用 p 命名空间
创建时间: | 2018/7/19 9:19 |
更新时间: | 2018/7/19 14:27 |
作者: | 1876333166@qq.com |
-
为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。
-
Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性。
-
使用 p 命名空间后,基于 XML 的配置方式将进一步简化
-
使用此种方式配置之前需要先导入p命名空间。方法与之前导入util命名空间类似:
-
导入方法Spring配置文件 ----> 找到Namespaces ---> 勾选p ----> 完成
第一步编写实体类
实体类User
package com.yirong.bean;
public class User {
private Car car; //Car属性定义
private String name; //name属性定义
}
//实体类Car
package com.yirong.bean;
public class Car {
private String name;
}
<!-- p引用属性赋值
p:car-ref : 标示引用其他的bean
p:name :标示给当然 User实体类的属性name赋值
-->
<bean id="user" class="com.yirong.bean.User" p:car-ref="car" p:name="张三"></bean>
<!-- 配置Car的bean -->
<bean id="car" class="com.yirong.bean.Car"></bean>
8.utility scheme 定义集合
创建时间: | 2018/7/19 14:27 |
更新时间: | 2018/7/19 18:25 |
作者: | 1876333166@qq.com |
-
使用基本的集合标签定义集合时, 不能将集合作为独立的 Bean 定义, 导致其他 Bean 无法引用该集合, 所以无法在不同 Bean 之间共享集合.
-
可以使用 util schema 里的集合标签定义独立的集合 Bean. 需要注意的是, 必须在 <beans> 根元素里添加 util schema 定义
-
如果想用util schema来定义集合,需要先导入util命名空间,具体方法是在配置文件编辑窗口找到Namespaces选项卡,然后加选util命令空间(打上勾表示选中)就可以了
第一步实体类定义
//属性静态常量
public static final String str = "hello";
第二步配置文件配置bean
<!-- <util:constant> 引用某个类型public static 域,并将其暴露为bean -->
<util:constant static-field="com.yirong.entry.User.str" id="str" />
<bean id="user" class="com.yirong.entry.User">
<constructor-arg name="map" ref="map"></constructor-arg>
<constructor-arg name="properties" ref="properties"></constructor-arg>
</bean>
<!-- 供其他bean引用 -->
<util:properties id="properties">
<prop key="user">root</prop>
<prop key="password">root</prop>
<prop key="url">jdbc:mysql://localhost:3306/test</prop>
</util:properties>
<!-- <util:map> 创建一个java.util.map类型的bean,其中包含值或者引用 -->
<util:map id="map">
<entry key="key1" value="1"></entry>
<entry key="key2" value="2"></entry>
<entry key="key3" value="3"></entry>
<entry key="key4" value="4"></entry>
</util:map>
<!-- <util:constant> 引用某个类型public static 域,并将其暴露为bean
<util:list> 创建一个java.util.list类型的bean,其中包含值或者引用
<util:properties> 创建一个java.util.properties类型的bean
<util:property-path> 引用一个属性(或内嵌属性),并将其暴露为bean
<util:set> 创建一个java.util.set类型的bean,其中包含值或者引用 -->
<util:constant static-field="com.yirong.entry.User.str" id="str" />
9.Bean 自动装配
创建时间: | 2018/7/19 18:25 |
更新时间: | 2018/7/19 20:25 |
作者: | 1876333166@qq.com |
-
Spring IOC 容器可以自动装配 Bean. 需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式
-
byType(根据类型自动装配): 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这种情况下, Spring 将无法判定哪个 Bean 最合适该属性, 所以不能执行自动装配.
-
byName(根据名称自动装配): 必须将目标 Bean 的名称和属性名设置的完全相同.
-
constructor(通过构造器自动装配): 当 Bean 中存在多个构造器时, 此种自动装配方式将会很复杂. 不推荐使用
第一步创建实体类
private Car car;
private String name;
第二步配置spring文件
<!-- 自动装配 autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”
1.constructor – 在构造函数参数的byType方式。
2.byType – 按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
3.byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
4.no – 缺省情况下,自动配置是通过“ref”属性手动设定 -->
<!-- 使用构造自动装配 -->
<bean id="constructor_user" class="com.yirong.auto.User" autowire="constructor">
<constructor-arg name="name" value="小明"></constructor-arg>
</bean>
<bean id="car1" class="com.yirong.auto.Car"> <property name="speed" value="200"></property>
</bean>
<!-- 使用autowire="byType"类型自动装配 -->
<bean id="aoto_user" class="com.yirong.auto.User" autowire="byType"></bean>
<bean id="car1" class="com.yirong.auto.Car"> <property name="speed" value="200"></property>
</bean>
<!-- 使用autowire="byName"名字自动装配 -->
<bean id="aoto_user2" class="com.yirong.auto.User" autowire="byName"></bean>
<bean id="car" class="com.yirong.auto.Car">
<property name="speed" value="200"></property>
</bean>
需要注意,使用按类型装配bean方式配置的时候配置文件中该类型的bean只能有一个,否则就会出现问题
10.继承 Bean
创建时间: | 2018/7/19 18:52 |
更新时间: | 2018/7/20 14:13 |
作者: | 1876333166@qq.com |
-
Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean
-
继承仅仅是指配置上的继承,并不意味着这两个bean之间存在继承关系。继承bean配置仅仅是为了复用其配置信息。
-
子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置
-
子 Bean 也可以覆盖从父 Bean 继承过来的配置
-
父 Bean 可以作为配置模板, 也可以作为 Bean 实例. 若只想把父 Bean 作为模板, 可以设置 <bean> 的abstract 属性为true, 这样 Spring 将不会实例化这个 Bean
-
并不是 <bean> 元素里的所有属性都会被继承. 比如: autowire, abstract 等.
-
也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置. 但此时 abstract 必须设为 true
<bean id="address"
class="cn.edu.nuc.spring.beans.relation.Address"
p:city="Beijing" p:street="WuDaokou"/>
<bean id="address2" p:street="DaZhongsi" parent="address"/>
<!-- 抽象bean:bean的abstract属性为true的bean。这样的bean不能被ioc容器实例化,只能被用来继承配置。若某一个bean的class属性没有指定,则该bean必须是一个抽象bean -->
<bean id="address" p:city="Beijing" p:street="WuDaokou"
abstract="true"/>
<!-- bean配置的继承:使用bean的parent属性指定继承那个bean -->
<bean id="address2" p:street="DaZhongsi" parent="address"/>
Bean 的作用域
-
在 Spring 中, 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域.
-
默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域.
<bean id="car" class="cn.edu.nuc.spring.beans.scope.Car">
<property name="brand" value="Audi"/>
<property name="price" value="300000"/>
</bean>
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-scope.xml");
//不管调用几次都只会实例化一次,因为bean的scope属性默认是singleton单利
Car car1 = (Car) ctx.getBean("car");
Car car2 = (Car) ctx.getBean("car");
System.out.println(car1 == car2);
}
<!-- 使用bean的scope属性来配置bean的作用域
singleton:默认值。容器初始化时创建bean实例,整个容器的生命周期内只创建这一个bean。单例的
prototype:原型的。容器初始化时不创建bean实例,而在每次请求时都创建一个新的bean实例,并返回。
-->
<bean id="car" class="cn.edu.nuc.spring.beans.scope.Car"
scope="prototype">
<property name="brand" value="Audi"/>
<property name="price" value="300000"/>
</bean>
11.使用外部属性文件
创建时间: | 2018/7/20 14:15 |
更新时间: | 2018/7/20 15:24 |
作者: | 1876333166@qq.com |
-
在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离
-
Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量.
-
Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用。
-
Spring 2.5 之后: 可通过 <context:property-placeholder> 元素简化:
-
<beans> 中添加 context Schema 定义
-
在配置文件中加入如下配置:
-
<!-- 导入属性文件 -->
<context:property-placeholder location="文件路径"/>
使用外部属性文件配置数据源
第一步创建配置文件
user=root
password=root
url=jdbc:mysql://localhost:3306/mysql
driverClass=com.mysql.jdbc.Driver
第二步配置数据源bean
<!-- 导入属性文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 使用外部类的属性,需要导入c3p0的jar -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="driverClass" value="${driverClass}"></property>
</bean>
public static void main(String[] args) throws SQLException {
ApplicationContext a = new ClassPathXmlApplicationContext("applicationContext.xml");
<!-- 返回数据源的对象 -->
DataSource dataSource = (DataSource) a.getBean("dataSource");
System.out.println(dataSource.getConnection());
}
12.基于注解的方式配置Bean
创建时间: | 2018/7/23 8:26 |
更新时间: | 2018/7/23 9:34 |
作者: | 1876333166@qq.com |
-
组件扫描(component scanning): Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件.
-
特定组件包括:
-
@Component: 基本注解, 标识了一个受 Spring 管理的组件
-
@Respository: 标识持久层组件
-
@Service: 标识服务层(业务层)组件
-
@Controller: 标识表现层组件
-
-
对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称
当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明
<!--
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.
resource-pattern :只扫描指定的包路径下的文件
-->
<!-- <context:component-scan base-package="com.yirong.annotation" resource-pattern="controller/*.class"></context:component-scan>
context:include-filter :使用需要修改下面的use-default-filters参数为false默认是true
use-default-filters="false"
-->
<context:component-scan base-package="com.yirong.annotation" >
<!-- 加载不包含的目标类 -->
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> -->
<!-- 加载包含的目标类 -->
<!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> -->
</context:component-scan>
实现的实体类如下:
package com.yirong.annotation;
importorg.springframework.stereotype.Component;
@Component //如果去掉注解UserRespositoryImpl类注入时会抛异常所有使用 @Autowired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Autowired 注解的 required 属性为 false
public class User {
}
public interface UserRespository {
void save();
}
@Repository
public class UserRespositoryImpl implements UserRespository {
//注入user
@Autowired(required=false)
private User user;
@Override
public void save() {
System.out.println("UserRespositoryImpl save....");
}
}
public interface UserService {
void save();
}
每个注解后面都有默认的id,类名首字母小写如果需要指定其他的类名可以如下:
@Service(value="userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserRespository userRespository;
@Override
public void save() {
userRespository.save();
System.out.println("UserServiceImpl save ......");
}
}
@Controller
public class UserController {
@Autowired
private UserService userService;
public void save() {
userService.save();
}
}
-
@Autowired 注解自动装配具有兼容类型的单个 Bean属性
-
构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Autowired 注解
-
默认情况下, 所有使用 @Autowired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Autowired 注解的 required 属性为 false
-
默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称.Spring 允许对方法的入参标注 @Qualifier 已指定注入 Bean 的名称
-
@Autowired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
-
@Autowired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.
-
@Autowired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值
-
13.spring表达式语言:SpEL
创建时间: | 2018/8/2 11:36 |
更新时间: | 2018/8/2 11:41 |
作者: | 1876333166@qq.com |
-
Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
-
语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL
-
SpEL 为 bean 的属性进行动态赋值提供了便利
-
通过 SpEL 可以实现:
-
通过 bean 的 id 对 bean 进行引用
-
调用方法以及引用对象中的属性
-
计算表达式的值,正则表达式的匹配
-
SpEL:字面量(了解即可,不常用)
-
字面量的表示:
-
整数:<property name="count" value="#{5}"/>
-
小数:<property name="frequency" value="#{89.7}"/>
-
科学计数法:<property name="capacity" value="#{1e4}"/>
-
String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/>
-
Boolean:<property name="enabled" value="#{false}"/>
-
SpEL:引用 Bean、属性和方法
<!-- 配置bean容器 -->
<bean id="car" class="com.yirong.bean.Car">
<!-- 给Car类中的属性赋值 -->
<property name="price" value="3000"></property>
<property name="name" value="abcd"/>
</bean>
<!-- 配置bean容器 -->
<bean id="user" class="com.yirong.bean.User">
<!-- 使用Spel方法给属性赋值,类似与ref="car" -->
<property name="car" value="#{car}"></property>
<!-- 使用Spel表达式对属性进行赋值,单引号与双引号标示值为String类型 -->
<property name="name" value="#{'张三'}"></property>
<!-- 使用Spel表达式赋值,boolean 类型赋值,true,false -->
<property name="bool" value="#{true}"></property>
<!-- 类似与if,else判断语句 -->
<property name="pric" value="#{car.price==3000 ? 0:1}"></property>
<!-- car.name,取得数据是Car类中的name属性值,转换成大写 -->
<property name="str" value="#{car.name.toUpperCase()}"></property>
</bean>
14.IOC 容器中 Bean 的生命周期方法
创建时间: | 2018/8/2 11:44 |
更新时间: | 2018/8/2 14:12 |
作者: | 1876333166@qq.com |
-
Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.
-
Spring IOC 容器对 Bean 的生命周期进行管理的过程:
-
通过构造器或工厂方法创建 Bean 实例
-
为 Bean 的属性设置值和对其他 Bean 的引用
-
调用 Bean 的初始化方法
-
Bean 可以使用了
-
当容器关闭时, 调用 Bean 的销毁方法
-
-
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.
第一步创建实体类
public class Car {
public Car() {
System.out.println("car's constructor...");
}
private String brand;
public void setBrand(String brand) {
System.out.println("set brand...");
this.brand = brand;
}
public void init() {
System.out.println("init...");
}
public void destory() {
System.out.println("destory...");
}
}
第二步编写配置
init-method="init" bean的初始化方法,destroy-method="destory" 销毁方法
<bean id="car" class="cn.edu.nuc.spring.cycle.Car"
init-method="init" destroy-method="destory">
<property name="brand" value="Audi"/>
</bean>
第三步main方法测试
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("beans-cycle.xml");
Car car = (Car) ctx.getBean("car");
System.out.println(car);
ctx.close(); //关闭Ioc容器
}
15.创建 Bean 的工厂方法
创建时间: | 2018/8/2 14:13 |
更新时间: | 2018/8/2 14:27 |
作者: | 1876333166@qq.com |
-
调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节.
-
要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 <constrctor-arg> 元素为该方法传递方法参数.
工厂方法分为静态工厂,与实例工厂
-
实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节.
-
要声明通过实例工厂方法创建的 Bean
-
在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
-
在 factory-method 属性里指定该工厂方法的名称
-
使用 construtor-arg 元素为工厂方法传递方法参数
-
第一步创建静态工厂方法
/**
* 静态工厂方法:通过静态方法返回bean的实例
* @author Administrator
*/
public class CarFactory {
private static Map<String, Car> map = new HashMap<String, Car>();
static {
map.put("car1", new Car("audi1", 1000000));
map.put("car2", new Car("audi2", 1000000));
}
//静态方法
public static Car getCar(String name) {
return map.get(name);
}
}
创建实例工厂的实例
/**
* 实例工厂方法:即需要创建工厂本身在调用工厂的实例方法,返回工厂实例
* @author Administrator
*/
public class IntanceCarFactory {
private Map<String, Car> map;
public IntanceCarFactory() {
map = new HashMap<>();
map.put("car1", new Car("car2", 300000));
}
//实例方法
public Car getCar(String name) {
return map.get(name);
}
}
第二步配置Bean
<!-- 配置Car的bean -->
<bean id="car" class="com.yirong.bean.Car"></bean>
<!--
通过静态工厂方法来配置Bean, 注意:不是配置静态方法实例,而是配置bean实例
class属性 :指向静态工厂方法的全类名
factory-method :指向静态工厂方法的方法名
constructor-arg : 如果工厂方法需要传入参数,则使用constructor-arg,设置参数
-->
<bean id="carfactory" class="com.yirong.bean.factory.CarFactory" factory-method="getCar">
<constructor-arg value="car2"></constructor-arg>
</bean>
<!-- 配置工厂的实例 -->
<bean id="carfactory1" class="com.yirong.bean.factory.IntanceCarFactory"></bean>
<!-- 通过实例工厂,返回工厂的实例 -->
<bean id="car1" factory-bean="carfactory1" factory-method="getCar">
<constructor-arg value="car1"></constructor-arg>
</bean>
第三步测试方法
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) act.getBean("carfactory");
System.out.println(car);
Car car1 = (Car) act.getBean("car1");
System.out.println(car1);
Car car2 = (Car) act.getBean("carfactoryBean");
System.out.println(car2);
}
实现 FactoryBean 接口在 IOC 容器中配置 Bean范例
-
Spring 中有两种类型的 Bean, 一种是普通Bean, 另一种是工厂Bean, 即FactoryBean.
-
工厂 Bean 跟普通Bean不同, 其返回的对象不是指定类的一个实例, 其返回的是该工厂 Bean 的 getObject 方法所返回的对象
/**
* 创建factoryBean的方法,需要实现FactoryBean<Car>
* @author Administrator
*
*/
public class CarfactoryBean implements FactoryBean<Car>{
private String name;
public void setName(String name) {
this.name = name;
}
//返回的对象
@Override
public Car getObject() throws Exception {
return new Car(name, 5000000);
}
//返回对象的类型
@Override
public Class<?> getObjectType() {
return Car.class;
}
//返回单利
@Override
public boolean isSingleton() {
return true;
}
}
配置文件
<!-- 通过FactoryBean来配置Bean的实例
class :指向FactoryBean的全类名
property : 配置FactoryBean的实例
但实际返回的是FactoryBean的getObject() 方法,返回的实例
-->
<bean id="carfactoryBean" class="com.yirong.bean.factoryBean.CarfactoryBean">
<property name="name" value="MBW"></property>
</bean>
16.泛型依赖注入
创建时间: | 2018/8/2 14:36 |
更新时间: | 2018/8/2 14:37 |
作者: | 1876333166@qq.com |
-
Spring 4.x 中可以为子类注入子类对应的泛型类型的成员变量的引用
17.Aop动态代理
创建时间: | 2018/8/2 15:27 |
更新时间: | 2018/8/2 15:44 |
作者: | 1876333166@qq.com |
-
代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上.
第一步创建接口方法类
public interface Algorithm {
public int add(int i,int j);
public int aub(int i,int j);
public int mul(int i,int j);
public int div(int i,int j);
}
第二步创建实现类实现接口的方法
@Component(value="algorithmImpl")
public class AlgorithmImpl implements Algorithm{
@Override
public int add(int i, int j) {
System.out.println("这个是加法运算" + i + "+" + j);
int result = i + j;
System.out.println("计算结果是:" + result);
return result;
}
}
第三步创建代理类
/**
* 动态代理类,实现代理
* @author Administrator
*/
public class CalculatorLoggingHandler {
//代理对象
private Algorithm target;
public CalculatorLoggingHandler(Algorithm target) {
this.target = target;
}
public Algorithm gettargetProxy() {
Algorithm proxy = null;
//代理对象由哪一个加载器类进行加载
ClassLoader loader = target.getClass().getClassLoader();
//代理对象的类型,其中有哪些方法
Class [] arg1 = new Class[] {Algorithm.class};
//当调用代理对象的类型,即执行的方法
InvocationHandler h = new InvocationHandler() {
/**
* proxy : 正在代理的对象,一般不调用
* method : 正在被调用的方法
* arg2 : 调用时传入的参数
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] arg2) throws Throwable {
String methodName = method.getName();
//日志
System.out.println("这个是"+methodName+"运算" + Arrays.asList(arg2));
//执行方法
Object retult = method.invoke(target, arg2);
System.out.println("这个是"+methodName+"运算计算结果是" + retult);
return retult;
}
};
proxy = (Algorithm) Proxy.newProxyInstance(loader, arg1, h);
return proxy;
}
}
测试方法
public static void main(String[] args) {
// 初始化
Algorithm target = new AlgorithmImpl();
//初始化代理对象
Algorithm proxy = new CalculatorLoggingHandler(target).gettargetProxy();
//使用代理执行方法
int result = proxy.add(1, 5);
System.out.println(result);
result = proxy.div(4, 2);
System.out.println(result);
}
18.Aop切面,基于 注解的方式声明切面
创建时间: | 2018/8/2 15:47 |
更新时间: | 2018/8/2 16:12 |
作者: | 1876333166@qq.com |
-
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
-
通知(Advice): 切面必须要完成的工作
-
目标(Target): 被通知的对象
-
代理(Proxy): 向目标对象应用通知之后创建的对象
-
连接点(Joinpoint):程序执行的某个特定位置:个如类某方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为ArithmethicCalculator#add(); 方位为该方法执行前的位置
-
切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
-
AspectJ:Java 社区里最完整最流行的 AOP 框架.
-
在 Spring2.0 以上版本中, 可以使用基于 AspectJ 注解或基于 XML 配置的 AOP
在Spring中启用Aspectj注解支持
-
要在 Spring 应用中使用 AspectJ 注解, 必须在 classpath 下包含 AspectJ 类库: aopalliance.jar、aspectj.weaver.jar 和 spring-aspects.jar
-
将 aop Schema 添加到 <beans> 根元素中.
-
要在 Spring IOC 容器中启用 AspectJ 注解支持, 只要在 Bean 配置文件中定义一个空的 XML 元素 <aop:aspectj-autoproxy>
-
当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时, 会自动为与 AspectJ 切面匹配的 Bean 创建代理.
-
AspectJ 支持 5 种类型的通知注解:
-
@Before: 前置通知, 在方法执行之前执行
-
@After: 后置通知, 在方法执行之后执行
-
@AfterRunning: 返回通知, 在方法返回结果之后执行
-
@AfterThrowing: 异常通知, 在方法抛出异常之后
-
@Around: 环绕通知, 围绕着方法执行
-
-
最典型的切入点表达式时根据方法的签名来匹配各种方法:
-
execution * com.atguigu.spring.ArithmeticCalculator.*(..): 匹配 ArithmeticCalculator 中声明的所有方法,第一个 * 代表任意修饰符及任意返回值. 第二个 * 代表任意方法. .. 匹配任意数量的参数. 若目标类与接口与该切面在同一个包中, 可以省略包名.
-
execution public * ArithmeticCalculator.*(..): 匹配 ArithmeticCalculator 接口的所有公有方法.
-
execution public double ArithmeticCalculator.*(..): 匹配 ArithmeticCalculator 中返回 double 类型数值的方法
-
execution public double ArithmeticCalculator.*(double, ..): 匹配第一个参数为 double 类型的方法, .. 匹配任意数量任意类型的参数
-
execution public double ArithmeticCalculator.*(double, double): 匹配参数类型为 double, double 类型的方法.
-
第一步创建接口与实现类
public interface Algorithm {
public int add(int i,int j);
public int div(int i,int j);
}
//注解把当前AlgorithmImpl交给Spring容器进行管理
@Component
public class AlgorithmImpl implements Algorithm{
@Override
public int add(int i, int j) {
int result = j + j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
第二步日志文件
/**
* 日志文件
* @author Administrator
*/
// 把这个类声明为一个切面,需要把该类放入到Ioc容器中,在声明一个切面
@Order(1) //如果有多个日志文件可以使用order注解设置切面的优先级 数字越大优先级越高
@Aspect
@Component
public class AlgorithmLoggin {
/**
* 声明切入点的方法
* 合并切入点表达式,使用注解 @Pointcut
*/
@Pointcut("execution(* *.*(int, int))")
private void pointCutOperation(){}
// 在目标方法之后执行,
@After("pointCutOperation()")
public void afterMethod(JoinPoint joinPoint) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("这个" + methodName + "方法正在结束");
}
// 声明该方法是一个前置通知,在目标方法之前执行JoinPoint连接点
// execution 匹配方法执行的连接点
@Before("pointCatOperation()")
public void beforeMethod(JoinPoint joinPoint) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("正在执行的" + methodName + "方法" + Arrays.asList(joinPoint.getArgs()));
}
/**
* 执行目标方法时发生异常执行
* @param joinPoint
* @param e
*/
@AfterThrowing(pointcut = "pointCatOperation()", throwing = "e")
public void AfterThrowingMethod(JoinPoint joinPoint, Exception e) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("这个是" + methodName + "方法" + "出了异常:" + e);
}
/**
* 必须在通知方法的签名中添加一个同名参数. 在运行时, Spring AOP 会通过这个参数传递返回值. returning 返回参数的结果
* @param joinPoint
*/
@AfterReturning(pointcut = "pointCatOperation()", returning = "restult")
public void AfterReturningMethod(JoinPoint joinPoint, Object restult) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("正在执行的" + methodName + "方法" + "-----》结果是:" + restult);
}
/**
* 环绕通知类似与动态代理 连接点的参数类型必须是 ProceedingJoinPoint proceed() 方法来执行被代理的方法.
* @throws Throwable
*/
/*
* @Around("execution(* com.yirong.beans.aop.Algorithm.*(int, int))") public
* Object AroundMethod(ProceedingJoinPoint joinPoin) throws Throwable {
*
* //执行方法 Object retult = null; try { //前置通知 System.out.println("正在执行的" +
* joinPoin.getSignature().getName() + "方法" +
* Arrays.asList(joinPoin.getArgs())); retult = joinPoin.proceed(); //后置通知
* System.out.println("这个" + joinPoin.getSignature().getName() + "方法正在结束"); }
* catch (Throwable e) { //异常通知 System.out.println("这个是" +
* joinPoin.getSignature().getName() + "方法" + "出了异常:" + e); throw e; }
*
* //返回通知
*
* return retult; }
*/
}
第三步测试方法
public static void main(String[] args) {
// 配置IOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 从IOC容器中取出bean的实例
Algorithm algorithm = applicationContext.getBean(Algorithm.class);
// 执行对应的方法
int result = algorithm.div(4, 2);
System.out.println(result);
}
第四步配置xml文件
<!-- 配置扫描的包 -->
<context:component-scan base-package="com.yirong.beans.aop"></context:component-scan>
<!-- 启用 AspectJ 注解支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
19.基于 XML配置声明切面
创建时间: | 2018/8/2 16:09 |
更新时间: | 2018/8/2 16:25 |
作者: | 1876333166@qq.com |
第一步接口和实现类
public interface Algorithm {
public int add(int i,int j);
public int div(int i,int j);
}
public class AlgorithmImpl implements Algorithm{
@Override
public int add(int i, int j) {
int result = j + j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
第二步写日志类
/**
* 日志类
* @author Administrator
*/
public class LogginAspect {
// 在目标方法之后执行,
public void afterMethod(JoinPoint joinPoint) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("这个" + methodName + "方法正在结束");
}
public void AfterThrowingMethod(JoinPoint joinPoint, Exception e) {
// 获取连接点的方法签名对象的名字
String methodName = joinPoint.getSignature().getName();
System.out.println("这个是" + methodName + "方法" + "出了异常:" + e);
}
}
第三步写XML文件
<!-- 配置实现类的bean -->
<bean id="algorithmImpl" class="com.yirong.beansxml.aop.AlgorithmImpl"></bean>
<!-- 配置日志类的bean -->
<bean id="logginAspect" class="com.yirong.beansxml.aop.LogginAspect"></bean>
<!-- 配置Aop
-
定义在 <aop:aspect> 元素下: 只对当前切面有效
-
定义在 <aop:config> 元素下: 对所有切面都有效
-->
<aop:config>
<!-- 配置切点的表达式 -->
<aop:pointcut expression="execution(* *.*(int, int))" id="poincut"/>
<!-- 配置切面 -->
<aop:aspect ref="logginAspect">
<!-- 配置后置通知 -->
<aop:after method="afterMethod" pointcut-ref="poincut"/>
<aop:after-throwing method="AfterThrowingMethod" pointcut-ref="poincut" throwing="e"/>
</aop:aspect>
</aop:config>
第四步写测试文件
public static void main(String[] args) {
// 配置IOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beansxml-aop.xml");
// 从IOC容器中取出bean的实例
Algorithm algorithm = (Algorithm) applicationContext.getBean("algorithmImpl");
// 执行对应的方法
int result = algorithm.div(4, 0);
System.out.println(result);
}
20.JdbcTemplate, JdbcDaoSupport 示例代码,具名参数
创建时间: | 2018/8/2 16:27 |
更新时间: | 2018/8/2 16:40 |
作者: | 1876333166@qq.com |
-
为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架.
-
作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法. 每个模板方法都能控制整个过程, 并允许覆盖过程中的特定任务. 通过这种方式, 可以在尽可能保留灵活性的情况下, 将数据库存取的工作量降到最低.
第一步写测试类
public class TestjdbcTmplate {
DataSource dataSource = null;
JdbcTemplate jdbcTemplate = null;
NamedParameterJdbcTemplate namedParameterJdbcTemplate = null;
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-jdbctemplate.xml");
dataSource = (DataSource) ctx.getBean("dataSource");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
}
/**
* 使用具名参数
* 优点就是:当字段较多,不用考虑字段的顺序,效率高,即key,value的形式
* 缺点:麻烦代码量多
*
*/
@Test
public void testNameParter() {
String sql = "insert into emp values(null,:b,:c,:d,:w)";
Map<String, Object> paramMap=new HashMap<String,Object >();
paramMap.put("b", "man");
paramMap.put("c", "25");
paramMap.put("d", "18612396984");
paramMap.put("w", "18612396984");
int update = namedParameterJdbcTemplate.update(sql, paramMap);
System.out.println(update);
}
/**
* 测试数据源是否连接成功
* @throws SQLException
*/
@Test
public void test() throws SQLException {
System.out.println(dataSource.getConnection());
}
/**
* 查询实体类的集合
* Name name 使用别名的方式
*/
@Test
public void testqueryForList() {
String sql = "select id,Name name,address,age,phone from emp where id > ?";
RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
List<Emp> query = jdbcTemplate.query(sql, rowMapper,1);
System.out.println(query);
}
/**
* 查询单条记录
* queryForObject(String sql, RowMapper<Emp> rowMapper, Object... args)
*/
@Test
public void testqueryForobject() {
String sql = "select id,Name name,address,age,phone from emp where id > ?";
RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
Emp queryForObject = jdbcTemplate.queryForObject(sql, rowMapper, 1);
System.out.println(queryForObject);
}
/**
* 修改单条数据
*/
@Test
public void testUpdate() {
String sql = "update emp set name = ? where id = ?";
int result = jdbcTemplate.update(sql, "lisi",1);
System.out.println(result);
}
/**
* 执行批量插入数据
* batchArgs: 是一个集合参数,因为集合中有多个数据,所以是Object[] 数组类型
*/
@Test
public void testbatchUpdate() {
String sql = "insert into emp values(?,?,?,?,?)";
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(new Object[]{null,"张三",20,"广州市",10000});
int[] result = jdbcTemplate.batchUpdate(sql, batchArgs);
System.out.println(result);
}
/**
* 查询数据库中的记录总数
* queryForObject
*/
@Test
public void testad() {
String sql = "select count(*) from emp";
int count = jdbcTemplate.queryForObject(sql,Integer.class);
System.out.println(count);
}
}
JDBCDaoSupper类,作用与jdbcTemplate一样,一般使用jdbcTmplate
@Repository
public class JdbcDaoSupper extends JdbcDaoSupport{
/**此处必须加入dataSource或jdbcTemplate要么报错如下
* Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
* 如不加jdbcTemplate。要用dataSource
* name只能重新加入dataSource,为什么我用了setDataSource22为DataSource赋值
* 因在JdbcDaoSupport类中为final关键字修饰,不可重写
* @param dataSource
*/
@Autowired
public void setDataSource22(DataSource dataSource) {
setDataSource(dataSource);
}
public List<Emp> testqueryForList(int id){
String sql = "select id,Name name,address,age,phone from emp where id > ?";
RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
return getJdbcTemplate().query(sql, rowMapper,id);
}
}
第二步编写properties文件
user=root //root:数据库用户
password=root //root:数据库密码
url=jdbc:mysql://localhost:3306/user //localhost:ip地址,localhost代表本地,3306:端口号,user:数据库名称
driverClass=com.mysql.jdbc.Driver //musql数据库的驱动
第三步编写XML文件
<!-- 配置扫描的包 -->
<context:component-scan base-package="com.yirong"></context:component-scan>
<!-- 引入外部文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 配置数据库的数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="testConnectionOnCheckin" value="false"/>
<property name="testConnectionOnCheckout" value="true"/>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="jdbcDaoSupper" class="com.yirong.dao.JdbcDaoSupper">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置具名参数bean -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
21.Spring 中的事务管理
创建时间: | 2018/8/2 16:41 |
更新时间: | 2018/8/2 16:46 |
作者: | 1876333166@qq.com |