java高新技术(二)


 

7JavaBean内省

8beanutils工具包

9注解

10泛型

11AOP


 

7JavaBean内省

 



javaBean
是一种特殊的java类主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。一个类被当做javaBean使用时,javaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

java
的注解
注解被用来为程序元素设置元数据,它并不影响程序代码的执行,即无论增加什么注释,程序执行都不受影响,java的注解采用@标记形式,后跟上注解类型名称,在JDK中java.lang包中预定义了三种注解,分别是:Override,Deprecated和SuppressWarnings.
重写
Override
Override是一个限定重写方法的注解类型,用来指明被注解的方法必须是重写超类方法的方法,这个注解只能用于方法上,编译器在编译源代码时会检查用@Override标注的方法是否有重写父类的方法

警告Deprecated
Deprecated是用来标记已过时成员的注解类型,用来指明被注解的方法是一个过时的方法,不建议使用了,当编译调用到被标注为Deprecated的方法的类时,编译器就会产生警告。

抑制警告SuppressWarnings
SuppressWarnings是抑制编译器警告的注解类型,用来指明被注解的方法,变量或类在编译时如果有警告信息,就阻止警告。

 

 

8beanutils工具包

我们在操作JavaBean的时候 我们可以用Introspector的方式来操作,但是呢这样需要我们写大量的代码 。

Apache小组为我们提供了很有用的工具包来操作JavaBean 也就是BeanUtils工具包 ,这个可以到apache.org 上面下载 commons-BeanUtils工具包,同时我们也要下载Logging也就是日志工具包 。

 

我们下载好了BeanUtils工具包之后 打开之后 发现你面有一个docs那个就是帮助文档 介绍了 Beanutils工具包中各种类的使用 ,这里 我们主要用到BeanUtils类

 

BeanUtils类中的所有方法都是静态方法 我们通过它的getPropertysetProperty方法 等等方法 这里我们主要用到BeanUtils类

9注解


注解被用来为程序元素设置元数据,它并不影响程序代码的执行,即无论增加什么注释,程序执行都不受影响,java的注解采用@标记形式,后跟上注解类型名称,在JDK中java.lang包中预定义了三种注解,分别是:Override,Deprecated和SuppressWarnings.
重写
Override
Override是一个限定重写方法的注解类型,用来指明被注解的方法必须是重写超类方法的方法,这个注解只能用于方法上,编译器在编译源代码时会检查用@Override标注的方法是否有重写父类的方法

警告Deprecated
Deprecated是用来标记已过时成员的注解类型,用来指明被注解的方法是一个过时的方法,不建议使用了,当编译调用到被标注为Deprecated的方法的类时,编译器就会产生警告。

抑制警告SuppressWarnings
SuppressWarnings是抑制编译器警告的注解类型,用来指明被注解的方法,变量或类在编译时如果有警告信息,就阻止警告。

10泛型



泛型是提供给JDBC编译器使用的,可以限定集合中的输入类型让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉"类型"信息,是程序运行效率不受影响,对于参数化的泛型类型 getClass()方法的返回值和原始类型完全一样由于编译生成的字节码会议去掉泛型的类型信息,只要能跳过编译器就可以往某个泛型集合中加入其它类型的数据。
泛型的思想是消除取用集合元素时代码中的强制类型转换,比如事先规定好一个集合中允许加入的具体元素类型,然后在编译环节实现集合中添加元素的类型检查,以防止有人将非预期类型的元素保存到集合中。
优点是类型错误可以在编译时暴露出来,而不是在运行时才发作(抛ClassCastException),这有助于早期错误排查,并提高程序的可靠性。
注意:
(1)JDK5.0后集合类定义像Vector一样都进行了泛型化改造,还有泛型类带有多个类型参数,如Map<K,V>就有两个类型参数,表示键-值映射。
(2)Java语言中的泛型是维护向后兼容的,即我们完全可以不采用泛型,而继续沿用过去的做法。
(3)在高版本开发环境中编译未启用泛型机制的集合类应用代码时,会输出编译提示信息。
11AOP
AOP:aspect oriented program.
不改变源代码,还给类增加新的功能.(代理)
Session s = SessionFactory.openSession();
Transaction tx = s.beginTransaction();
s.save(..);
tx.commit();
s.close();
切面:aspect,要实现的交叉功能
.
通知:切面的实际实现,比较具体(细化
).
连接点:可以将通知应用到目标程序中的地点.(方法调用,异常抛出,要修改的字段
)
切入点:真正的将通知应用到目标程序中的地点
.
引入:为类增加新的方法和属性
.
目标对象:被通知的对象
.
代理:把通知应用给目标对象以后,创建暂新的对象,该对象即为代理对象
.
织入:把通知应用给目标对象以后,创建暂新的对象的过程即为织入
.
1.编译期织入:当把java源代码编译成字节码class文件时,将通知织入.需要特殊的编译器
.
2.类装载期织入:当把class文件载入到jvm时,将通知织入
.
3.运行期(runtime)织入
:
spring代理方式

1.接口代理(jdk的动态代理):
2.对类代理(cglib代理
):
aop联盟
:
使用spring开发
aop:
1.引入aop联盟类库.(spring.jar已经内置了该包
)
2.引入cglib类库实现对类代理.${spring解压目录
}/lib/cglib/*.jar

PointCut{
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}

interface ClassFilter{
boolean isMatch(Class clazz);
}

interface Methodmatcher{
boolean matches(Method m,Class targetClass);1.
boolean isRuntime();2.
boolean matchers(Method m,Class target,Object[] args);3.
}

MethodBeforeAdvice|AfterReturningAdvice|MethodInterceptor
Advisor{

}
使用aspectj进行aop开发

1.引入aspectj类库
${spring解压目录}/lib/aspectj/*.jar
2.pojo:plain old java object.
使用
pojo + xml
dao:data access object.(数据访问对象
)

<!-- 创建目标对象
bean -->
<bean id="welcomeServiceTarget" class="cn.csdn.spring.service.WelcomeServiceImpl">
<property name="name" value="tom"/>
</bean>
<!-- 创建通知内容的
bean -->
<bean id="myMethodBeforeAdvice"class="cn.csdn.spring.advice.MyMethodBeforeAdvice"/>
<!-- 创建代理
bean
注意创建代理Bean需要有三个Property要设置,代理的接口(proxyInterfaces)也可以不写

-->
<bean id="welcomeService"class="org.springframework.aop.framework.ProxyFactoryBean">
<!--
接口 -->
<property name="proxyInterfaces">
<list>
<value>cn.csdn.spring.service.WelcomeService</value>
</list>
</property>

<!-- 要切入的通知内容
-->
<property name="interceptorNames">
<list>
<value>myMethodBeforeAdvice</value>
</list>
</property>

<!-- 选择目标对象
-->
<property name="target" ref="welcomeServiceTarget"/>
</bean>
//////////////////////////////////////////////
配置后置通知

1)定义通知
public class MyMethodAfterAdvice implements AfterReturningAdvice {
}
2)

<!-- 要切入的通知内容 -->
<property name="interceptorNames">
<list>
<value>myMethodBeforeAdvice</value>
<value>myMethodAfterAdvice</value>
</list>
</property>
/////////////////////////////////////////////
基于CGLIB的类代理

以前我们都是基于接口代理的:
得到对象的方式是:
WelcomeService ww=(WelcomeService) ac.getBean("welcomeService");
而现在我们将基于类进行代理
方法如下:
1)获得类对象的方式
WelcomeServiceImpl ww=(WelcomeServiceImpl)ac.getBean("welcomeService");
2
)修改配置文件
<!-- 设置基于类的代理 -->
<property name="proxyTargetClass" value="true"/>
///////////////////////////////////////////////////////
环绕通知:

环绕通知使用:
1)定义自己的异常处理类 MyAroundMethodAdvice
2)实现 ThrowsAdvice 接口
implementsMethodInterceptor
3)添加方法环绕通知方法:


public Object invoke(MethodInvocation Invocation) throws Throwable {
// TODO Auto-generated method stub

System.out.println("Around Start!");
//
调用目标方法
Invocation.proceed();

System.out.println("Around End!");
return Invocation;
}

4
)配置文件:
添加bean
<!-- 创建环绕通知
-->
<bean id="myAroundMethodAdvice"class="cn.csdn.spring.advice.MyAroundMethodAdvice"/>
代理通知
:
<property name="interceptorNames">
<list>
<value>myAroundMethodAdvice</value>
</list>
</property>
异常通知使用:

1)定义自己的异常处理类 MyMethodException
2)实现 ThrowsAdvice 接口
implementsThrowsAdvice
3)添加方法异常通知方法:

public void afterThrowing(Method method, Object[] args, Object target,Exception ex){
System.out.println("
当前方法:"+method+",参数个数:"+args.length+",目标对象:"+target.getClass().getName()+",异常类型:"+ex.getMessage());
}

4)配置文件:

添加bean
<!-- 创建异常通知类型
-->
<bean id="myMethodException" class="cn.csdn.spring.advice.MyMethodException"/>
代理通知
:
<property name="interceptorNames">
<list>
<value>myMethodException</value>
</list>
</property>
代理通知
:
<property name="interceptorNames">
<list>
<value>myMethodException</value>
</list>
</property>
5)在实际业务逻辑中产生一个异常

静态切入点:
切入点(advisor)包括:通知+要过滤的方法
1)配置步骤
在打招呼的接口中(GreetingService)定义方法eat()
并在实现类中,我们实现该方法,并且我们测试只给这个方法加上前置通知

2)修改配置文件
<!-- 配置静态切入点 -->
<bean id="beforeAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 配置通知
-->
<property name="advice" ref="myMethodBeforeAdvice"/>
<!-- 增加要过滤的方法
-->
<property name="mappedNames">
<list>
<value>eat</value>
</list>
</property>
</bean>
3)修改代理的通知

<!-- 要切入的通知内容 -->
<property name="interceptorNames">
<list>
<!--
<value>myMethodBeforeAdvice</value>
-->
<value>beforeAdvisor</value>
<value>myMethodAfterAdvice</value>
<value>myAroundMethodAdvice</value>
<value>myMethodException</value>
</list>
</property>
引入:为已经存在的类增加属性和方法

目标:
1)为目标对象添加属性
2)为目标对象添加方法
添加步骤:
1)定义ModifyDate接口(get、set方法)
2)实现接口,定义变量 重写get、set方法,继承DelegatingIntroductionInterceptor类
public class ModifyDateImpl extends DelegatingIntroductionInterceptorimplements ModifyDate {
private static final long serialVersionUID = 1L;
.......
3
)修改配置文件

1)增加引入通知(ModifyDateImpl)
<!-- 定义一个引入bean -->
<bean id="modifyDateImpl"class="cn.csdn.spring.service.ModifyDateImpl"/>
2)添加针对引入通知的默认的切入点()

<!-- 定义一个用于执行引入通知的默认切入点 -->
<bean id="defaultIntroductionAdvisor"class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg ref="modifyDateImpl"/>
</bean>
3)在代理通知(通知拦截)中增加

<value>defaultIntroductionAdvisor</value>使之代理默认的切入点
4)调试、测试
//获得修改类的对象

ModifyDate md=(ModifyDate)ww;
md.setModDate(Date.valueOf("2011-05-22"));
System.out.println(md.getModDate());

什么叫Aop?
Aspect Oriented Programming 面向方面编程

特点:
OOP(面向对象编程)
基于面向对象,进行高度封装,但是重复代码太多

举例 我有 20 类,每个类 5个方法。
需求:每个方法打印HelloWorld
OOP思想

1)每个方法都要 加System.out.println("HelloWorld");
2)肯定得修改源代码

3)代码重复量大
AOP思想 (能够实现不改变源代码,增加类新的功能)
1)能不能不改变 源代码 实现打印?
2)通过 切入点 完成 代理

3)重复劳动少了
AOP 常见术语
切面:需要实现的交叉功能
连接点:应用程序执行的过程中插入切面的地点(可以是方法,异常,修改字段)
通知:交叉功能(切面)的具体实现,通知是在“连接点”插入系统
切入点:已经被通知切入的连接点
引入:允许为已经存在的类添加新的方法或者属性
目标对象:被通知的类,它既可以是自己编写的类,也可以是添加定制的第三方的类。
代理:将通知应用到目标对象后产生的新的对象(代理对象)
织入:将切面应用到目标对象后产生的新的对象的“过程”,切面是在指定的连接点被织入到目标对象中
织入可以发生在对象生命周期的多个点(方法、异常)上
织入发生的时期:
编译期:切面在目标对象编译的时候织入
装载期:切面在目标对象被转载进JVM 的时候织入
运行期:切面在应用系统运行时织入(AOP将在织入切面时动态的产生委托代理对象)
AOP 的具体实现:
1)Java编写Spring的通知
2)Spring运行的时候通知对象
3)Spring实现了AOP联盟的接口
4)只支持方法连接点
AOP 创建代理的方式:
1)通过接口创建代理

2)通过类(cglib)创建代理
使用接口方式创建代理优于使用类创建代理

使用final的方法不能被通知


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值