我的Spring学习记录(二)
本篇就简单的说一下Bean的装配和AOP
本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的
1. 使用setter方法和构造方法装配Bean
1.1 前期准备
使用setter方法注入依赖其实在上一篇中已经遇到过了主要通过property在bean中进行注入
<!--声明一个bean并且指定相应的类-->
<bean name="dog" class="cn.lger.domain.Dog">
<property name="name" value="小美"/>
<property name="breed" value="土狗"/>
<property name="sex" value="母"/>
</bean>
上面在bean中使用 property
进行配置,用法是<property name="对象中的属性名" value="基本类型(与属性相互对应)">
但是,除了基本类型,对象这些复杂类型要怎么办?
比如有下面的一个实体类:Man
public class Man {
private Dog dog;
private Dog dog2;
/**
* 这里因为使用了有参的构造函数,所以需要写入无参构造函数
*/
public Man(){
}
/**
* 提供给Spring容器进行注入dog属性,这里将值赋值给dog2
*/
public Man(Dog dog) {
this.dog2 = dog;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void walkTheDog(){
System.out.println("遛"+dog.getName());
System.out.println("遛"+dog2.getName());
}
}
这个Man
有两只Dog
,此人要去遛狗,我们现在就帮助他获得dog
这里我们在配置文件中配置两个dog的bean,配置如下:
<bean name="dog" class="cn.lger.domain.Dog">
<property name="name" value="小美"/>
<property name="breed" value="土狗"/>
<property name="sex" value="母"/>
</bean>
<bean name="dog2" class="cn.lger.domain.Dog">
<property name="name" value="小美2"/>
<property name="breed" value="土狗"/>
<property name="sex" value="母"/>
</bean>
这里是关于Man
获取到两只dog的过程,也是bean的装配过程,Man
这个bean的声明过程
<bean name="man" class="cn.lger.domain.Man">
<!--通过ref映射将dog属性注入-->
<property name="dog" ref="dog"/>
<!--通过构造函数注入-->
<constructor-arg ref="dog2"/>
</bean>
首先我们是使用了setter方法注入我们的bean-->dog,这里我们只需要将value
改为ref
就可以使用复杂类型的注入工作了,但是有一个前提是你所需要注入的bean当然是由Spring管理了
然后是使用了构造函数进行注入,这里就要求我们在生成JavaBean的使用需要提供相应的构造方法,上面给出的Man
中有注释,经过构造方法后dog2属性将会产生一个叫小美2 的狗狗
1.2 代码测试
public class TestWiring {
/**
* 测试通过xml文件装配Bean到Man类
*/
@Test
public void test01(){
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Man man = applicationContext.getBean(Man.class);
man.walkTheDog();
}
}
//打印结果:遛小美
// 遛小美2
当我们的Man
去遛狗walkTheDog()
的时候这时候控制台打印的信息遛小美 遛小美2 让我们知道注入成功了
1.3 小结
我们需要明白,可以使用Spring这种在获取对象之前容器的加工能力获取一个有初始值的对象,可以方便我们的开发。每一个获取到的Bean都需要初始值的话这样我们可以解放很多劳动力,装配还可以通过SpEL(Spring Expression Language)这种表达式去注入一些东西,比如:dog2中的<property name="sex" value="#{dog.sex}"/>
,当然了,如果有机会的话我们可以一起探讨一下这个东西
还有就是,这里我所给出的装配Bean是一个简单的装配工作,还有集合(List、Map....)、工厂等方面的装配没有多做介绍,下面文章结束时会给出链接,里面会有装配方面更为详细的解释和操作:-)
2. AOP的使用
2.1 前期准备
在编程之前我们需要了解几个概念,这些概念性的东西我不是很喜欢,它总是让人混淆,或者有点烦。这里我用了自己的理解方式去解释
通知(Advice): 这可以理解为一段代码片,这段代码要让很多没有联系的对象用上,比如数据库中的连接开启与关闭,日志功能等,我们把这些代码使用Spring AOP用在其他对象的方法之前或者之后,这些代码块就可以称之为
通知
连接点(Joincut): 就是对象方法在使用时是能通过Spring调用
通知
的地方叫做连接点
切点(Pointcut): 就是对象方法在使用时是明确通过Spring调用
通知
的地方叫做切点
,就是说已经能够基本的确定这里需要插入一个通知
了切面(Aspect):
切面
是切点
和通知
的结合,就是说一个切面
就是通过通知
知道要干什么和切点
的在哪里干织入(Weaving):
织入
可以理解成一个过程,是通知
被应用到到切点
的这一个过程
当然了你可以去看下别人对这些概念的解释
http://www.cnblogs.com/hongwz/p/5764917.html
http://www.importnew.com/20748.html
看了以上的概念是不是对于AOP有了犯迷糊,是这样的,概念的东西还是需要捣鼓一下,其实我也不是很了解,但是,我们要用实例、实践去增加我们的理解,如果别人要我们解释总不能一行一行代码的说出来,同行之间总是要用一些术语交流的嘛,好,废话不说,继续AOP。
我们现在有一个Man,他现在要去上班了,但是又要去遛狗!!怎么办?可以请一个代理人啊,帮我们的Man去遛狗就行了。
pom.xml代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.lger</groupId>
<artifactId>spring-demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>spring-base</module>
</modules>
<properties>
<spring.version>4.3.10.RELEASE</spring.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--需要使用aop除了引入以上核心部分还要引入下面的两个依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
Man的代码如下:
public class Man {
public void noFreeTime(){
System.out.println("狗主人(被代理人)上班了");
}
}
代理人Proxy的代码如下:
public class Proxy {
public void before(){
System.out.println("代理人去被代理人家里牵狗,然后遛狗");
}
public void after(){
System.out.println("代理人带狗狗回家");
}
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--因为需要用到aop,所以需要引入新的约束,与上一篇的略有不同-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd ">
<bean name="man" class="cn.lger.domain.Man" />
<!--这是一个代理遛狗的人-->
<bean class="cn.lger.proxy.Proxy" name="proxy"/>
<!--
关于aop:pointcut的规则
<aop:pointcut id="walkTheDog" expression="execution(* cn.lger.domain.Man.noFreeTime())"/>
id->pointcut标识,具有唯一性
expression是填入一个表达式,表达式中可以使用的有execution()/within()...
我们这里使用的是execution(),里面的填入是一个关于切入点的信息比如我要Man中的所有方法都能被代理则
我们可以一步步推出来,如下:
void cn.lger.domain.Man.noFreeTime()//public 可以不写
* cn.lger.domain.Man.noFreeTime()//* 返回任意类型
* cn.lger.domain.Man.*(..)//任意方法、任意参数
-->
<!--配置aop-->
<aop:config>
<!--切入点-->
<aop:pointcut id="walkTheDog" expression="execution(* cn.lger.domain.Man.*(..))"/>
<!--切面-->
<aop:aspect id="proxy" ref="proxy">
<aop:before method="before" pointcut-ref="walkTheDog"/>
<aop:after method="after" pointcut-ref="walkTheDog"/>
<!--这里的method除了上面的after和before还有其他的,可以google或者百度,当然看文档也是可以的-->
</aop:aspect>
</aop:config>
</beans>
2.2 代码测试
/**
* 测试AOP是否配置成功
*/
@Test
public void test01(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Man man = context.getBean(Man.class);
man.noFreeTime();
}
//打印结果
// 代理人去被代理人家里牵狗,然后遛狗
// 狗主人上班了
// 代理人带狗狗回家
通过以上的代码测试,说明了在执行noFreeTime()
的时候就会执行我们在配置中配置的proxy.before()
和proxy.after()
方法。为什么会这样,这其实和我们Java学习中的动态代理是差不多的,但是Spring的实现更为复杂,它不要求我们实现什么接口,它是基于cglib动态代理的,这里就不作展开,可以自己了解。
以上的代码(包括上一篇)都可以在github下载
可能自己知识储备不是充足,也有一些错误,给出以下链接可供学习
关于Spring装配
|- http://www.cnblogs.com/jingmoxukong/p/4532680.html
|- http://www.cnblogs.com/DeepLearing/p/5670516.html
|- http://www.cnblogs.com/mesopotamia/p/4950927.html
|- http://www.cnblogs.com/mlj5288/articles/4535451.html
关于Spring AOP
|- http://www.cnblogs.com/hongwz/p/5764917.html
|- http://www.cnblogs.com/frankliiu-java/archive/2010/01/05/1639664.html
|- http://blog.csdn.net/u010987379/article/details/52152925
我的Spring学习记录(二)的更多相关文章
- Spring学习记录(二)---容器和bean属性配置
下载spring包,在eclipse搭建spring环境. 这步我在eclipse中无法导入包,看网上的: http://sishuok.(和谐)com/forum/blogPost/list/242 ...
- Spring学习记录(二)
1.Spring中的AOP思想 aop思想:横向重复,纵向抽取. AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(Aspect),通知(Advice),连 ...
- Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客
==他的博客应该不错,没有细看 Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客 http://blog.csdn.net/u012706811/article/det ...
- 我的Spring学习记录(四)
虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...
- Material Calendar View 学习记录(二)
Material Calendar View 学习记录(二) github link: material-calendarview; 在学习记录一中简单翻译了该开源项目的README.md文档.接下来 ...
- 我的Spring学习记录(五)
在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...
- Spring 学习记录3 ConversionService
ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...
- Spring 学习记录8 初识XmlWebApplicationContext(2)
主题 接上文Spring 学习记录7 初识XmlWebApplicationContext refresh方法 refresh方法是定义在父类AbstractApplicationContext中的. ...
- Spring 学习记录6 BeanFactory(2)
主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...
随机推荐
- SVG交互动画制作
前面我们已经说过了要怎样制作CSS3动画,但是SVG动画一直都没有时间研究过,正好趁现在有一点时间静下心来研究一下. 一般来说,常见前端动画实现方案分为三种,CSS3动画,HTML动画(SVG动画), ...
- BotVS开发基础—Python API
代码 import json def main(): # python API列表 https://www.botvs.com/bbs-topic/443 #状态信息 LogStatus(" ...
- python+selenium自动化软件测试(第7章):Page Object模式
什么是Page ObjectModel模式Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页 ...
- python基础教程(九)
python异常 python用异常对象(exception object)来表示异常情况.遇到错误后,会引发异常.如果异常对象并未被处理或捕捉,程序就会用所谓的 回溯(Traceback, 一种错误 ...
- js实现非模态窗口增加数据后刷新父窗口数据
父窗口是由两个部分组成,一个html的table,一部分是extjs的gird. 点击grid面板[增加]按钮将会弹出非模态窗口进行新数据的编辑页面 下面是按钮的触发函数代码: var a = win ...
- Android项目实战(三十四):蓝牙4.0 BLE 多设备连接
最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...
- Flask01 路由控制(转换器)、反转、请求方法控制
1 提出问题 如何实现前端传过去的路径时动态的(即:多个url对应一个url视图函数) 例如: 浏览器中输入 http://127.0.0.1:5000/test/good/ 或者 http://12 ...
- 谈谈.NET,Java,php
开通博客后,一直都是转点别的朋友写的有意思的博文,今天我来写我在博客园的第一篇文章,说的不对的地方请你指正.希望本文能为一些准备学习编程的朋友有一点帮助. 开发桌面程序一直都是c语言,c++的天下,因 ...
- 数据结构学习:KMP模式匹配算法
有关KMP的算法具体的实现网上有很多,不具体阐述.这里附上c的实现. 谈谈我自己的理解.KMP相较于朴素算法,其主要目的是为了使主串中的遍历参数i不回溯,而直接改变目标串中的遍历参数j. 比如说要是目 ...
- 我的hibernate学习记录(一)
之前已经过滤一下hibernate的简单的用法,但是近期有点时间,所以重新看下视频,敲下代码,翻下笔记,写博客与大家分享一下. hibernate简介 Hibernate是一个开放源代码的对象关系映射 ...