属性编辑器: PropertyEditorSupport
作用:如果一个类中的属性为Date类型,那么在beans.xml中设置的Date值不能与Date匹配,那么我们需要对beans.xml中的属性进行编辑,让它转化为Date类型的
CustomEditorConfigurer可以读取实现java.beans.PropertyEditor接口的类,将字符串转为指定的类型,更方便的使用PropertyEditorSupport.PropertyEditorSupport实现PropertyEditor,必须重新定义setAsText
程序目标:如果bean类中有不是一般类型的属性的话,并且在xml文件中有这个属性的赋值,那么可以使用属性编辑器对属性进行类型的封装,然后通过org.springframework.beans.factory.config.CustomEditorConfigurer类在xml中与属性编辑器处理类绑定
接口:
package yuchen.dataeditor;
public interface A {
public void display();
}
实现类:
package yuchen.dataeditor;
import java.util.Date;
public class AImp implements A {
private Date date;
public void display() {
// TODO Auto-generated method stub
if(date instanceof Date){
System.out.println(date);
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
属性编辑器类
package yuchen.dataeditor;
import java.beans.PropertyEditorSupport;//属性编辑器
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateEditor extends PropertyEditorSupport {
private Date date;
@Override
public void setAsText(String str) throws IllegalArgumentException {
// TODO Auto-generated method stub
String[] a=str.split("/");
int year = Integer.parseInt(a[0]);
int month = Integer.parseInt(a[1]);
int day = Integer.parseInt(a[2]);
Calendar cal= new GregorianCalendar(year,month-1,day);
date = cal.getTime();
}
@Override
public Object getValue() {
// TODO Auto-generated method stub
return date;
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="a" class="yuchen.dataeditor.AImp">
<property name="date">
<value> 1998/07/07 </value>
</property>
</bean>
<bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean
class="yuchen.dataeditor.DateEditor"/>
</entry>
</map>
</property>
</bean>
</beans>
Test:
package yuchen.dataeditor;
/*
* 属性编辑器:java.beans.PropertyEditorSupport
* 如何知道属性编辑器类为谁服务呢?
* <bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean
class="yuchen.dataeditor.DateEditor"/>
</entry>
</map>
</property>
</bean>
*/
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/dataeditor/beans.xml");
A aa=(A) context.getBean("a");
aa.display();
}
}
属性设置器:
除了通过beans.xml设置属性以外,还可以通过PropertyPlaceholderConfigurer为bean属性设置值,它利用属性文件
程序目标:测试PropertyPlaceholderConfigurer类
接口:
package yuchen.propertyphc;
public interface A {
public void display();
}
实现类:
package yuchen.propertyphc;
import java.util.Date;
public class AImp implements A {
private Date date;
public void display() {
// TODO Auto-generated method stub
if(date instanceof Date){
System.out.println(date);
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
属性编辑器:
package yuchen.propertyphc;
import java.beans.PropertyEditorSupport;//属性编辑器
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateEditor extends PropertyEditorSupport {
private Date date;
@Override
public void setAsText(String str) throws IllegalArgumentException {
// TODO Auto-generated method stub
String[] a=str.split("/");
int year = Integer.parseInt(a[0]);
int month = Integer.parseInt(a[1]);
int day = Integer.parseInt(a[2]);
Calendar cal= new GregorianCalendar(year,month-1,day);
date = cal.getTime();
}
@Override
public Object getValue() {
// TODO Auto-generated method stub
return date;
}
}
属性文件:
date= 2001/10/3
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="a" class="yuchen.propertyphc.AImp">
<property name="date">
<value>${date}</value>
</property>
</bean>
<bean
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean
class="yuchen.propertyphc.DateEditor"/>
</entry>
</map>
</property>
</bean>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigur
er">
<property name="locations">
<list>
<value>yuchen/propertyphc/AImp.properties</value>
</list>
</property>
</bean>
</beans>
Test:
package yuchen.propertyphc;
/*
* 属性设置器:
* 通过属性文件给bean的属性设置值
* 在beans.xml中添加属性设置器类:
* <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigur
er">
<property name="locations">
<list>
<value>yuchen/propertyphc/AImp.properties</value>
</list>
</property>
</bean>
属性文件:
date= 2001/10/3
*/
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/propertyphc/beans.xml");
A aa=(A) context.getBean("a");
aa.display();
}
}
属性覆盖器:
作用:属性文件中设置好的属性值将会覆盖掉beans.xml中类属性值
接口:
package yuchen.propertypoc;
public interface A {
public void display();
}
实现类:
package yuchen.propertypoc;
import java.util.Date;
public class AImp implements A {
private String name;
public void display() {
// TODO Auto-generated method stub
System.out.println(this.name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="a" class="yuchen.propertypoc.AImp">
<property name="name">
<value>zhao</value>
</property>
</bean>
<bean
class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
>
<property name="location">
<value>yuchen/propertypoc/AImp.properties</value>
</property>
</bean>
</beans>
属性文件:
a.name=yuchen
Test:
package yuchen.propertypoc;
/*
* 覆盖:
* 使用PropertyOverrideConfigurer那么属性文件中设置的属性值
* 会覆盖在beans.xml 的bean类中设置的属性值
*/
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/propertypoc/beans.xml");
A aa=(A) context.getBean("a");
aa.display();
}
}
ApplicationContext的事件特性(观察者模式):
1.ApplicationContext发布事务
2.事件响应者需要实现ApplicationListener
3.定义一个事件类,继承ApplicationEvent
接口:
package yuchen.event;
public interface Model {
public String superDate();
public void update();
}
接口:
package yuchen.event;
public interface View {
public void display();
}
实现类:
package yuchen.event;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
public class ModelImpl implements Model,ApplicationContextAware{
private String name;
private ApplicationContext context;
public String superDate() {
// TODO Auto-generated method stub
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void update(){
this.setName("zhang");
if(context!=null){
context.publishEvent(new RefreshEvent(this,"update
()"));
}else{
System.out.println("null");
}
}
public void setApplicationContext(ApplicationContext arg0) throws
BeansException {
// TODO Auto-generated method stub
context=arg0;
}
}
实现类:
package yuchen.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class ViewImpl implements View,ApplicationListener{
private Model model;
public void display() {
// TODO Auto-generated method stub
String rst=model.superDate();
System.out.println(rst);
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
public void onApplicationEvent(ApplicationEvent arg0) {
// TODO Auto-generated method stub
if(arg0 instanceof RefreshEvent){
System.out.println("事件发生后调用onApplicationEvent方法");
this.display();
}
}
}
事件类:
package yuchen.event;
import org.springframework.context.ApplicationEvent;
public class RefreshEvent extends ApplicationEvent{
private String message;
public RefreshEvent(Object arg0,String message) {
super(arg0);
this.message=message;
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="model" class="yuchen.event.ModelImpl">
<property name="name">
<value>yuchen</value>
</property>
</bean>
<bean id="view" class="yuchen.event.ViewImpl">
<property name="model">
<ref bean="model"></ref>
</property>
</bean>
</beans>
Test:
package yuchen.event;
/*
* 程序目标:当更新model里的name时,context发布事件,再次调用display方法
* ApplicationContext用来发布事件
* ApplicationEvent为事件的抽象类,需要继承此类声明一个事件对象
* ApplicationListener监听器监听是否有事件发生,当context发布事件
* 后,会调用实现了此接口的bean中的onApplicationEvent()方法
* 实现ApplicationContextAware的类可获得context
*/
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("yuchen/event/beans.xml");
View v=(View) context.getBean("view");
v.display();
System.out.println("----------------");
ModelImpl m=(ModelImpl)context.getBean("model");
m.update();
}
}
国际化:
ApplicationContext的getMessage方法可以做国际化
并且在beans.xml中需要配置国际化文件的路径
修改上面的类:将消息的内容国际化
ModelImpl.java:
public void update(){
this.setName("zhang");
if(context!=null){
//context.publishEvent(new RefreshEvent(this,"update()"));
context.publishEvent(new RefreshEvent(this,context.getMessage("message", new String[]{"message","!!!!!"}, Locale.CHINA)));
}else{
System.out.println("null");
}
}
加入国际化属性文件:
message_zh.properties:
message = {0} /u5237/u65b0 {1}
Message_en.properties:
message = {0} refresh{1}
修改beans.xml:
加入:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>yuchen/event/message</value>
</list>
</property>
</bean>
工厂bean:
以前的程序都是通过容器产生工厂,容器的表现有两种
1.XmlBeanFactory
2.ApplicationContext
现在不用得到工厂,通过一个工厂bean去得到bean实例
产生的实例为工厂bean创建的产品,并不是工厂对象
package yuchen.factorybean;
import java.util.Properties;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
Test:
public class Test {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ApplicationContext factory = new
ClassPathXmlApplicationContext("yuchen/factorybean/beans.xml");
long s = (Long)factory.getBean("a");
System.out.println(s);
String classpath = (String)factory.getBean("classpath");
System.out.println(classpath);
FactoryBean o =(FactoryBean)factory.getBean("&classpath");
String classpath2 = (String)o.getObject();
System.out.println(classpath2);
}
}
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="a"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property
name="targetClass"><value>java.lang.System</value></property>
<property
name="targetMethod"><value>currentTimeMillis</value></property>
</bean>
<bean id="props"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="java.lang.System"></property>
<property name="targetMethod" value="getProperties"/>
</bean>
<bean id="classpath"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref
local="props"/></property>
<property name="targetMethod"
value="getProperty"></property>
<property name="arguments">
<value>java.class.path</value>
</property>
</bean>
</beans>
面向方面编程AOP:
1.什么是面向方面编程?有什么用?
2.一个陈旧的案例
3.AOP的一些概念
4.第一个AOP程序
5.前置Advice
6.后置Advice
7.环绕Advice
8.异常抛出Advice
什么是面向方面编程?有什么用?
面向方面编程就是就是将类中掺杂的与业务无关的代码抽象出来,以便重用
作用:重用,解耦合
包含两个要素:
1.在哪里加入服务(方法前?方法后?属性?)
2.具体为哪个类的哪个方法或属性加入服务
例如:
1.要在方法前加入事务服务
2.为A类的sayhello()业务方法加入服务
两者组合就是一个方面
一个陈旧的案例:
程序目标:为A类的业务方法1加入事务和安全的服务,为业务方法2只加入事务的服务
package yuchen.aop.oldcase;
public class OldCase {
public void execute1(){
safetybackcheck();
System.out.println("事务开始代码");
this.operation1();
System.out.println("事务结束代码");
}
public void execute2(){
System.out.println("事务开始代码");
this.operation2();
System.out.println("事务结束代码");
}
public void safetybackcheck(){
System.out.println("安全检查代码");
}
public void operation1(){
System.out.println("业务代码1");
}
public void operation2(){
System.out.println("业务代码2");
}
}
发现问题:业务代码和服务代码互相掺杂,结构不清晰,维护代码不方便,也不方便重用
那么使用AOP编程就是为了解决这个问题
AOP的一些概念:
关注点:业务核心代码(如: operation1)和系统服务代码(事务,安全代码)都是关注点
横切关注点:程序中的系统服务代码都是横切关注点
核心关注点:就是业务核心代码
方面(aspect):advice+pointcut=aspect,一个方面说明了为哪些类的哪些方法,属性等加入哪些服务,例如:为A类的a()方法加入事务,安全服务,这就是方面
advice: 在哪里加入服务(方法前?方法后?属性?),就是拦截器
pointcut: 具体为哪个类的哪个方法或属性加入服务
连接点:能插入服务的位置是连接点:如:方法,属性,异常抛出,Spring Aop只支持一种类型的连接点(方法)
织入(weaving):就是将方面加入到具体的哪个对象中
Aop代理:Aop Proxy:代理对象,他去调用被包装了服务的业务方法
AOP的目标就是要将横切关注点与核心关注点分离,实现解耦合,重用这些服务
第一个AOP程序:
接口:
package yuchen.aop.firstaop;
public interface Business {
public void business1();
public void business2();
}
核心业务类:
package yuchen.aop.firstaop;
public class BusinessImpl implements Business {
public void busMethod1(){
this.business1();
}
public void busMethod2(){
this.business2();
}
public void business1() {
// TODO Auto-generated method stub
System.out.println("核心业务方法1");
}
public void business2() {
// TODO Auto-generated method stub
System.out.println("核心业务方法2");
}
}
安全服务:
package yuchen.aop.firstaop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class SecuityBeforeAdvice implements MethodBeforeAdvice{
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// TODO Auto-generated method stub
this.check();
}
public void check(){
System.out.println("安全检查");
}
}
事务服务:
package yuchen.aop.firstaop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AffairAroundAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation arg0) throws Throwable {
// TODO Auto-generated method stub
this.transactionStart();
Object object=arg0.proceed();
this.transactionEnd();
return object;
}
public void transactionStart(){
System.out.println("事务开始");
}
public void transactionEnd(){
System.out.println("事务结束");
}
}
事务服务pointcut:
package yuchen.aop.firstaop;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
public class PointcutImpl extends StaticMethodMatcherPointcut{
public boolean matches(Method arg0, Class arg1) {
// TODO Auto-generated method stub
if(arg0.getName().equals("business1")){
return true;
}
return false;
}
@Override
public ClassFilter getClassFilter() {
// TODO Auto-generated method stub
return new ClassFilter(){
public boolean matches(Class arg0) {
// TODO Auto-generated method stub
return (arg0==BusinessImpl.class);
}
};
}
}
Test:
package yuchen.aop.firstaop;
/*
* 为类中的某些方法加上事务和安全
*/
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ProxyFactory pf=new ProxyFactory();
Business bi=new BusinessImpl();
SecuityBeforeAdvice sb=new SecuityBeforeAdvice();
Pointcut p=new PointcutImpl();
Advisor advisor=new DefaultPointcutAdvisor(p,sb);
AffairAroundAdvice ad=new AffairAroundAdvice();
pf.addAdvisor(advisor);
pf.addAdvice(ad);
pf.setTarget(bi);
Business b=(Business) pf.getProxy();
b.business1();
b.business2();
}
}
开发步骤:
1.写核心业务类
2.写系统服务类(advice)
3.选择性的写过滤类(pointcut)
4.写客户代码:通过DefaultPointcutAdvisor将advice and pointcut组装,代理工厂添加advice,设置目标对象,生成代理对象,代理对象调用业务方法
使用proxyfactorybean方式:
添加配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="businessimpl" class="yuchen.aop.updatefirstaop.BusinessImpl">
</bean>
<bean id="secuity" class="yuchen.aop.updatefirstaop.SecuityBeforeAdvice">
</bean>
<bean id="affair" class="yuchen.aop.updatefirstaop.AffairAroundAdvice">
</bean>
<bean id="pointcutimpl" class="yuchen.aop.updatefirstaop.PointcutImpl">
</bean>
<bean id="befadvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice">
<ref local="secuity"></ref>
</property>
<property name="pointcut">
<ref local="pointcutimpl"></ref>
</property>
</bean>
<bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="businessimpl"></ref>
</property>
<property name="interceptorNames">
<list>
<value>befadvisor</value>
<value>affair</value>
</list>
</property>
</bean>
</beans>
修改Test:
package yuchen.aop.updatefirstaop;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/updatefirstaop/beans.xml");
Business b=(Business) context.getBean("factory");
b.busMethod1();
}
}
前置Advice:
接口:
package yuchen.aop.before.proxyfactory;
public interface Business {
public void busMethod1();
public void busMethod2();
}
核心业务实现类:
package yuchen.aop.before.proxyfactory;
public class BusinessImpl implements Business {
public void busMethod1(){
this.business1();
}
public void busMethod2(){
this.business2();
}
public void business1() {
// TODO Auto-generated method stub
System.out.println("核心业务方法1");
}
public void business2() {
// TODO Auto-generated method stub
System.out.println("核心业务方法2");
}
}
实体类:
package yuchen.aop.before.proxyfactory;
public class UserInfo {
private String username;
private String password;
public UserInfo() {
super();
}
public UserInfo(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
用户登陆管理类:
package yuchen.aop.before.proxyfactory;
public class UserMagager {
private static ThreadLocal t=new ThreadLocal();
public static void login(String username,String password){
t.set(new UserInfo(username,password));
}
public static void logout(){
t.set(null);
}
public static UserInfo getUserInfo(){
return (UserInfo)t.get();
}
public static void validate(){
UserInfo user=getUserInfo();
if(user==null){
throw new UserInfoException("您还没有登陆");
}else if(user.getUsername().equals("admin")){
System.out.println("系统管理员登陆");
}else{
throw new UserInfoException("您不是系统管理员");
}
}
}
自定义异常:
package yuchen.aop.before.proxyfactory;
public class UserInfoException extends RuntimeException {
public UserInfoException(String msg){
super(msg);
}
}
前置advice:
package yuchen.aop.before.proxyfactory;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class SecuityBeforeAdvice implements MethodBeforeAdvice{
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// TODO Auto-generated method stub
UserMagager.validate();
}
}
Test:
package yuchen.aop.before.proxyfactory;
/*
* 当抛出异常的时候,拦截器中断
*/
import org.springframework.aop.framework.ProxyFactory;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Business bi=getProxyFactory();
try{
bi.busMethod1();
}catch(UserInfoException ue){
System.out.println(ue.getMessage());
}
UserMagager.login("admin", "1234");
bi.busMethod1();
UserMagager.logout();
UserMagager.login("yuchen", "123");
try{
bi.busMethod1();
}catch(UserInfoException ue){
System.out.println(ue.getMessage());
}
}
public static Business getProxyFactory(){
ProxyFactory pf=new ProxyFactory();
Business business=new BusinessImpl();
SecuityBeforeAdvice sa=new SecuityBeforeAdvice();
pf.setTarget(business);
pf.addAdvice(sa);
return (Business)pf.getProxy();
}
}
采用声明服务方式:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="businessimpl" class="yuchen.aop.before.proxyfactorybean.BusinessImpl">
</bean>
<bean id="secuity" class="yuchen.aop.before.proxyfactorybean.SecuityBeforeAdvice">
</bean>
<bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="businessimpl"></ref>
</property>
<property name="interceptorNames">
<list>
<value>secuity</value>
</list>
</property>
</bean>
</beans>
修改Test:
package yuchen.aop.before.proxyfactorybean;
/*
* 当抛出异常的时候,拦截器中断
*/
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/before/proxyfactorybean/beans.xml");
Business business=(Business) context.getBean("factory");
UserMagager.login("admin", "123");
business.busMethod1();
business.busMethod2();
UserMagager.logout();
UserMagager.login("yuchen", "1");
try{
business.busMethod1();
}catch(UserInfoException ue){
System.out.println(ue.getMessage());
}
UserMagager.logout();
try{
business.busMethod1();
}catch(UserInfoException ue){
System.out.println(ue.getMessage());
}
}
}
后置Advice:
实体类:
package yuchen.aop.after.proxyfactory;
/*
* 业务类
*/
public class Man {
private String name;
private int age;
public Man() {
super();
}
public Man(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Man growup(){
++age;
return this;
}
}
核心业务类:
package yuchen.aop.after.proxyfactory;
/**
* 服务:方法计数器
*/
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Counter {
private static Map countmap=new HashMap();//存方法名和调用次数
public Map getCountmap() {
return countmap;
}
public void setCountmap(Map countmap) {
this.countmap = countmap;
}
public void count(Method method){
count(method.getName());
}
//计算方法调用的次数并保存到一个map表中
public void count(String name){
Integer i=(Integer) countmap.get("name");
if(i!=null){
countmap.put(name, new Integer(i.intValue()+1));
}else{
countmap.put(name, 1);
}
}
//返回方法调用的次数
public int getCount(String name){
int x;
Integer i=(Integer) countmap.get(name);
if(i==null){
x=0;
}else{
x=i.intValue();
}
return x;
}
}
后置advice:
package yuchen.aop.after.proxyfactory;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class CountAgeAfterAdvice extends Counter implements AfterReturningAdvice{
public void afterReturning(Object returnvalue, Method method, Object[] parameter, Object target) throws Throwable {
// TODO Auto-generated method stub
//returnvalue:被拦截的方法的返回值
//method:被拦截的方法
//parameter:被拦截的方法的参数
//target:被拦截的目标对象
this.count(method);//被拦截的对象的方法调用后执行
if(method.getName().equals("growup")){
Man man=(Man)returnvalue;
System.out.println(man.getName()+":"+man.getAge());
System.out.println(this.getCount(method.getName()));
}
}
}
Test:
package yuchen.aop.after.proxyfactory;
import org.aopalliance.aop.Advice;
import org.springframework.aop.framework.ProxyFactory;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Man man=new Man("yuchen",24);
CountAgeAfterAdvice counter=new CountAgeAfterAdvice();
ProxyFactory pf=new ProxyFactory();
pf.addAdvice(counter);
pf.setTarget(man);
Man m=(Man) pf.getProxy();
m.growup();
}
}
声明式:xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="man" class="yuchen.aop.after.proxyfactorybean.Man">
<property name="name">
<value>yuchen</value>
</property>
<property name="age">
<value>24</value>
</property>
</bean>
<bean id="counterage" class="yuchen.aop.after.proxyfactorybean.CountAgeAfterAdvice">
</bean>
<bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="man"></ref>
</property>
<property name="interceptorNames">
<list>
<value>counterage</value>
</list>
</property>
</bean>
</beans>
修改Test:
package yuchen.aop.after.proxyfactorybean;
import org.aopalliance.aop.Advice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/after/proxyfactorybean/beans.xml");
Man man=(Man) context.getBean("factory");
System.out.println(man.getName()+":"+man.getAge());
man.growup();
}
}
环绕Advice:
业务核心类:
package yuchen.aop.interception.proxyfactory;
public class AccountWork {
public void account(int num){
for(int i=0;i<num;i++){
work();
}
}
public void work(){
System.out.println("工作中....");
}
}
环绕advice:
package yuchen.aop.interception.proxyfactory;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;
public class AccountCapabilityAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
// TODO Auto-generated method stub
StopWatch sw=new StopWatch();
sw.start(invocation.getMethod().getName());
Object obj=invocation.proceed();
sw.stop();
this.displaybulletin(invocation, sw.getTotalTimeMillis());
return obj;
}
private void displaybulletin(MethodInvocation invocation,long l){
Method m=invocation.getMethod();
Object obj=invocation.getThis();
Object[] arg=invocation.getArguments();
System.out.println("目标类:"+obj.getClass().getName());
System.out.println("方法:"+m.getName());
System.out.print("方法参数:");
for(int i=0;i<arg.length;i++){
System.out.print(arg[i]);
if(i!=arg.length-1){
System.out.println(",");
}else{
System.out.println(".");
}
}
System.out.println("性能测试时间:"+l);
}
}
Test:
package yuchen.aop.interception.proxyfactory;
import org.springframework.aop.framework.ProxyFactory;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
AccountWork aa=getproxyfactory();
aa.account(100);
}
private static AccountWork getproxyfactory(){
ProxyFactory pf=new ProxyFactory();
AccountWork aw=new AccountWork();
AccountCapabilityAdvice aca=new AccountCapabilityAdvice();
pf.setTarget(aw);
pf.addAdvice(aca);
return (AccountWork)pf.getProxy();
}
}
声明方式:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="account" class="yuchen.aop.interception.proxyfactorybean.AccountWork">
</bean>
<bean id="acadvice" class="yuchen.aop.interception.proxyfactorybean.AccountCapabilityAdvice">
</bean>
<bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="account"></ref>
</property>
<property name="interceptorNames">
<list>
<value>acadvice</value>
</list>
</property>
</bean>
</beans>
修改Test:
package yuchen.aop.interception.proxyfactorybean;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/interception/proxyfactorybean/beans.xml");
AccountWork aw=(AccountWork) context.getBean("factory");
aw.account(100);
}
}
异常抛出Advice:
业务核心类:
package yuchen.aop.exception.proxyfactory;
import java.rmi.RemoteException;
public class ExceptionBean {
public void exception1() throws RemoteException{
throw new RemoteException("远程方法调用异常");
}
}
异常抛出advice:
package yuchen.aop.exception.proxyfactory;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import org.springframework.aop.ThrowsAdvice;
public class ExceptionAdvice implements ThrowsAdvice{
public void afterThrowing(Method method,Object[] args,Object target,RemoteException re){
System.out.println("抛出异常的方法名:"+method);
System.out.println("目标对象:"+target.getClass().getName());
System.out.println("异常信息:"+re.getMessage());
}
}
Test:
package yuchen.aop.exception.proxyfactory;
import java.rmi.RemoteException;
import org.springframework.aop.framework.ProxyFactory;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ExceptionBean bean=getProxyFactory();
try {
bean.exception1();
} catch (RemoteException e) {
// TODO Auto-generated catch block
}
}
public static ExceptionBean getProxyFactory(){
ProxyFactory pf=new ProxyFactory();
ExceptionBean eb=new ExceptionBean();
ExceptionAdvice ea=new ExceptionAdvice();
pf.setTarget(eb);
pf.addAdvice(ea);
return (ExceptionBean)pf.getProxy();
}
}
声明式方式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="bean" class="yuchen.aop.exception.proxyfactorybean.ExceptionBean">
</bean>
<bean id="advice" class="yuchen.aop.exception.proxyfactorybean.ExceptionAdvice">
</bean>
<bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="bean"></ref>
</property>
<property name="interceptorNames">
<list>
<value>advice</value>
</list>
</property>
</bean>
</beans>
修改Test:
package yuchen.aop.exception.proxyfactorybean;
import java.rmi.RemoteException;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context=new ClassPathXmlApplicationContext("yuchen/aop/exception/proxyfactorybean/beans.xml");
ExceptionBean bean=(ExceptionBean) context.getBean("factory");
try {
bean.exception1();
} catch (RemoteException e) {
// TODO Auto-generated catch block
}
}
}