首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Spring经典小结<2>

2013-11-23 
Spring经典总结25.各种类型数据的注入??1)基本数据注入?????利用value属性指定,可以注入字符串,数值等简

Spring经典总结<2>

5.各种类型数据的注入

??1)基本数据注入

?????利用value属性指定,可以注入字符串,数值等简单数据。

??*2)Bean对象注入

?????利用ref属性指定,可以注入一个Bean组件对象

<bean?id="hibernateCostDao"?class="com.tarena.dao.HibernateCostDAO">

</bean>

<!--?setter方式注入示例?-->

<bean?id="costAction"?scope="prototype"?

???????class="com.tarena.action.CostAction">

<!--?将ref指定的id属性Bean对象给costDao属性注入?-->

<property?name="costDao"?ref="hibernateCostDao">

</property>

????</bean>

??3)集合数据注入

? eg:

applicationContext.xml配置如下:

<bean?id="msgBean"?scope="singleton"?

class="com.tarena.service.MessageBean">

<!--?基本数据注入?-->

<property?name="name"?value="露丝">

</property>

<!--?其中,value值的类型全部为String型,对于age属性来说,其类型为Int

型,在属性注入时Spring会自动进行类型转换(String—>int)

?-->

<property?name="age"?value="18">

</property>

<!--?List集合注入?-->

<property?name="friends">

<list>

<value>TOM</value>

<value>JACK</value>

<value>张三丰</value>

</list>

</property>

<!--?Set集合注入?-->

<property?name="cities">

<set>

<value>北京</value>

<value>上海</value>

<value>深圳</value>

</set>

</property>

<property?name="includeTypes"?value="jpeg,gif,jpg">

</property>

<!--?Map集合注入?-->

<property?name="books">

<map>

<entry?key="1001"?value="Core?Java基础"></entry>

<entry?key="1002"?value="Struts框架详解"></entry>

<entry?key="1003"?value="编程之美"></entry>

</map>Spring经典总结

</property>

<!--?Properties(本质是Map)属性注入?-->

<property?name="dbParams">

<props>

<prop?key="username">root</prop>

<prop?key="password">1234</prop>

</props>

</property>

</bean>

测试类代码:

public?class?MessageBean?{

private?String?name;

private?int?age;

private?List<String>?friends;

private?Set<String>?cities;

private?Set<String>?types;

private?Map<Integer,?String>?books;

private?Properties?dbParams;

?

public?void?setDbParams(Properties?dbParams)?{

this.dbParams?=?dbParams;

}

?Spring经典总结

public?void?setIncludeTypes(String?str)?{

String[]?arr?=?str.split(",");

types?=?new?HashSet<String>();

for?(String?type?:?arr)?{

types.add(type);

}

}

?

public?void?setCities(Set<String>?cities)?{

this.cities?=?cities;

}

?

public?void?setFriends(List<String>?friends)?{

this.friends?=?friends;

}

?

public?void?show()?{

/**基本数据注入测试*/

System.out.println("姓名:"?+?name);

System.out.println("年龄:"?+?age);

/**List注入测试*/

System.out.println("---她的朋友---");

for?(String?s?:?friends)?{

System.out.println(s);

}

/**Set集合注入测试*/

System.out.println("---他们所在城市---");

for?(String?s?:?cities)?{

System.out.println(s);

}

System.out.println("---允许上传的图片类型---");

for?(String?s?:?types)?{

System.out.println(s);

}

/**Map集合注入测试*/

System.out.println("-----图书信息-----");

Set<Integer>?keys?=?books.keySet();

for?(Integer?key?:?keys)?{

System.out.println("编号:"?+?key?+?"?名字:"?+?books.get(key));

}

/**Properties注入测试*/

System.out.println("----连接参数-----");

Set<Object>?dbKeys?=?dbParams.keySet();

for?(Object?key?:?dbKeys)?{

System.out.println(key?+?":"?+?dbParams.getProperty(key.toString()));

}

}

public?void?setAge(int?age)?{

this.age?=?age;

}

public?void?setName(String?name)?{

this.name?=?name;

}

public?void?setBooks(Map<Integer,?String>?books)?{

this.books?=?books;

}

}

*6.什么是AOP,解决什么问题

?????Aspect?Oriented?Programming?面向方面编程也叫面向切面编程

面向方面编程是以(OOP)面向对象编程为基础,这两种编程思想侧重点不同。OOP侧重于对象,根据需求提炼出对象结构。AOP侧重于方面对象,方面(共同处理组件)关注的是共通处理部分,例如事务管理,权限控制,日志记录等。可以通过配置将其作用到某一个或多个目标对象上。好处是实现组件重复利用,改善程序结构,提高灵活性。将共同处理组件与目标对象解耦。

???AOP主要是解决一对多调用问题,一个共通组件被多个目标组件调用,降低组件关联。

*7.Spring容器AOP的基本使用

?1)引入spring-aop开发包

?2)编写方面组件,封装共通的处理逻辑

?3)在spring配置文件中,定义方面组件,利用aop配置,将方面组件方

????法和目标组件方法作用在一起。

8.?AOP相关概念

????*1)方面(Aspect)

????????方面(组件)指的是共同业务处理,可以切入到(即作用到)多个目标

????????对象,可以多次使用。

????*2)切入点(Pointcut)

????????切入点是连接点(Pintcut)的集合,采用表达式指定,用于指定哪些

????????组件和方法作为方面组件的切入目标。

*(1)方法限定表达式

???可以规定哪些方法被切入方面组件,哪些不被切入,也就是

???定义目标对象,格式如下:

execution(修饰符??返回类型?方法名(参数)?throws异常??)

???示例1:匹配容器中Bean对象的find开始的方法

???????????execution(*?find*(..))

第一个“*”表示返回类型不限,"find*"表示以“find

”开头的所有方法,".."表示一个或多个参数(也即参

数不限)

???示例2:匹配CostServiceImpl类中所有方法

???? ?execution(*?tarena.service.CostServiceImpl.*(..))

???示例3:匹配tarena.service包下所有类的所有方法

??? execution(*?tarena.service.*.*(..))

???示例4:匹配tarena.service包及其子包下所有类所有方法

??? execution(*?tarena.service..*.*(..))

???示例5:匹配容器Bean对象中的find开始的方法,并且是 public?void?修饰的

???? execution(public?void?find*(..))

???*(2).类型限定表达式

?????可以规定哪个类中的所有方法被切入方面组件

??格式:within(包名.类型名)

????示例1:匹配CostServiceImpl类中所有方法

?? ??within(tarena.service.CostServiceImpl)

????示例2:匹配tarena.service包下所有类所有方法

??? ???within(tarena.service.*)

????示例3:匹配tarena.service包及其子包中所有类所有方法

???? ??within(tarena.service..*)

???(3).Bean的Id或Name名称限定

?????可以按<bean>定义时,id或name属性值匹配??

??????bean(beanIdOrName)

??? ??示例1:匹配容器中id=costService的Bean对象

?????? ???bean(costService)

????示例2:匹配容器中id值以Service结尾的对象

???? ???bean(*Service)

???(4).参数类型限定

?????args(参数类型列表)

??? ?示例1:匹配有且只有一个参数,参数类型符合

???????????????Serializable类型的方法

????? ?args(java.io.Serializable)

???*注意:上述切入点表达式可以联合使用,采用&&,||连接

?????3)连接点(JoinPoint)

???????//?连接点的集合组成切入点,连接点指的是切面组件在目标对象上 // 作用的位置,例如:在方法调用前、方法调用后、或者发生异常。

???????切入点是连接点的集合。代表方面组件和某一个目标方法的关联点。

????*4)通知(Advice)

????????用于指定方面组件作用于目标对象中的目标方法的时机。例如前置

????????通知,意思是先执行方面组件,再执行目标方法。

?Spring提供了5种类型的通知。用于指定方面组件在目标方法哪个

?位置切入。Spring经典总结

???a.前置通知?<aop:before>

??????先执行方面组件,再执行目标组件方法

???b.后置通知?<aop:after-returning>

??????先执行目标组件方法,没有异常再执行方面组件。

??????如果发生异常,不会执行方面组件

???c.异常通知?<aop:after-throwing>

??????当目标方法抛出异常之后,执行方面组件。

???d.最终通知?<aop:after>

??????先执行目标方法,无论有没有异常都执行方面组件

???e.环绕通知?<aop:around>

??????相当于前置+后置通知。在目标方法前和后都执行方面组件

???内部实现原理:

try{

?????//前置通知切入

??//环绕前置通知切入

?????//目标组件方法

??//环绕后置通知切入

?????//后置通知切入

???}catch(){

????//异常通知切入

???}finally{

?????//最终通知切入

???}

?????5)目标对象(Target)

????????方面组件作用的对象,即与切入点表达式匹配的对象。

?????6)动态代理(AutoProxy)

???????Spring采用了动态代理技术实现了AOP控制。

?????? 如果Spring采用了AOP配置后,容器getBean方法返回的组件对象

????? 是代理对象(一个动态生成类型,即动态代理类),用户在使用时,由

???????代理对象调用切面组件和目标对象的功能。

?????Spring采用的动态代理技术有以下两种:

??????a.目标对象没有接口(使用cglib.jar工具包)

???? ?适用于目标组件没有接口实现的情况。

?public?class?$Service$$Enhancer$CGLIB?extends

?原目标组件类型{

????//重写目标对象的方法,在重写的方法中调用目标对象和方面组 ??件对象功能

?}

??b.目标对象有接口(采用JDK?Proxy?API)

??????适用于目标组件有接口实现的情况。

??????public?class?$Proxy4?implements?原目标组件接口{

?????????//重写目标接口方法,在重写的方法中调用目标对象和方面组件对?

???????????象功能

???????}

????public?void?testDelete()?{

String[]?confs?=?{?"applicationContext.xml"?};

ApplicationContext?ac?=?new?ClassPathXmlApplicationContext(confs);

CostService?service?=?(CostService)?ac.getBean("costService");

System.out.println("类名:"+service.getClass().getName());

//获得代理类中的所有public方法

????????????????Method[]?ms?=service.getClass().getMethods();

for(Method?m?:?ms){

System.out.println(m);

}

service.deleteCost();

}Spring经典总结

??? ??程序运行结果如下:

类名:$Proxy4

public?final?void?$Proxy4.addCost()

public?final?void?$Proxy4.deleteCost()

public?final?void?$Proxy4.findById()

public?final?boolean?$Proxy4.isFrozen()

public?final?org.springframework.aop.TargetSource?

??????$Proxy4.getTargetSource()

public?final?void?

??????$Proxy4.addAdvisor(int,org.springframework.aop.Advisor)?

?

??从以上结果可以看出,动态代理类中重写了原实现类中的

?????????addCost()、deleteCost()、findById()方法并加入了方面(共同

?????????处理的方法),这样就可以实现对目标对象实现方面切入。

?

热点排行