JavaEE框架——Spring入门基础(控制反转Ioc和切面技术Aop)

一.简介:

     Spring在英语中含义是春天,对于JavaEE开发者来说,Spring框架出现确实带来了一股全新的春天的气息。早在2002年,Rod Johson在其编著的Expert one to one J2EE design anddevelopment书中,对Java EE框架臃肿、低效、脱离现实的种种现状提出了很多质疑,并积极寻求探索革新之道。由他主导编写了interface21框架,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署轻量级开发框架。以interface21框架为基础,并集成了其它许多开源成果,于2004324日,发布了1.0正式版取名为Spring

    Spring的核心是个轻量级容器,实现了IoC(控制翻转)模式的容器,基于此核心容器所建立的应用程序,可以达到程序组件的松散耦合。这些特性都使得整个应用程序维护简化。Spring框架核心由下图所示的七个模块组成。





1、核心容器(Core)

        这是Spring框架最基础的部分,它提供了依赖注入(Dependency Injection)特征来实现容器对Bean的管理。这里最基本的概念是BeanFactory,它是任何Spring应用的核心。BeanFactory是工厂模式的一个实现,它使用IoC应用配置和依赖说明从实际的应用代码中分离出来

2AOP模块

      AOP即面向切面编程技术Spring在它的AOP模块中提供了对面向切面编程的丰富支持。AOP允许通过分离应用的业务逻辑与系统级服务(例如安全和事务管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责其它的系统级关注点,例如日志或事务支持

3、对象/关系映射集成模块ORM

     Hibernate是成熟的ORM产品,Spring并没有自己实现ORM框架而是集成了几个流行的ORM产品如HibernateJDOiBATIS。可以利用Spring对这些模块提供事务支持等。

4JDBC抽象和DAO模块

     Spring虽然集成了几个ORM产品,但也可以不选择这几款产品,因为Spring提供了JDBCDAO模块。该模块对现有的JDBC技术进行了优化。你可以保持你的数据库访问代码干净简洁,并且可以防止因关闭数据库资源失败而引起的问题

5SpringWeb模块

      Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文。另外,这个模块还提供了一些面向服务支持。例如:实现文件上传的multipart请求,它也提供了Spring和其它Web框架的集成,比如StrutsWebWork

6、应用上下文(Context)模块

       核心模块的BeanFactory使Spring成为一个容器,而上下文模块使它成为一个框架Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文。该模块还提供了一些面向服务支持这个模块扩展了BeanFactory的概念,增加了对国际化(I18N)消息、事件传播以及验证的支持。

      另外,这个模块还提供了许多企业服务,例如电子邮件、JNDI访问、EJB集成、远程以及时序调度(scheduling)服务。也包括对模版框架例如VelocityFreeMarker集成的支持。

7SpringMVC框架

      Spring为构建Web应用提供了一个功能全面的MVC框架。虽然Spring可以很容易地与其它MVC框架集成,例如Struts2,但SpringMVC框架使用IoC对控制逻辑和业务对象提供了完全的分离

二.Spring入门示例

        spring2.5基础包:spring.jar和commons-logging.jar

        spring3.x基础包:

  •  commons-logging.jar
  • org.springframework.asm-3.1.1.RELEASE.jar
  • org.springframework.beans-3.1.1.RELEASE.jar
  • org.springframework.context.support-3.1.1.RELEASE.jar
  • org.springframework.context-3.1.1.RELEASE.jar
  • org.springframework.core-3.1.1.RELEASE.jar
  • org.springframework.expression-3.1.1.RELEASE.jar

                                


建立好 web 工程或 Java 工程后 MyEclipse 可以加入 Spring 的支持, 导入 Spring 的核心包 。如果是 Eclipse 则在 Spring 网站上 下载 Spring 的核心 包并加入到工程中。

1、编写一个普通的Java类(JavaBean

package cn.hncu.s25.domain;

public class Person {
	private String name;
	private Integer age;
	
	public Person() {
		System.out.println("这是构造函数");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

2、在Spring配置文件applicationContext.xmlJavaBeanSpring容器来管理。(2.5和3.x版本不一致,这里一2.5版本为例)

<?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:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<bean id="p" class="cn.hncu.s25.domain.Person" scope="singleton"></bean>
</beans>


3、如何使用Spring容器配置的Bean

                BeanFactory factory=new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));//这是2.5版本的方法
		Person p=(Person) factory.getBean("p");
		System.out.println(p.hashCode());




三、Spring配置文件详解:

这个配置文件

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="p" class="cn.hncu.s3x.domain.Person">
		<property name="name" value="Jack"></property>
		<property name="age" value="23"></property>
	</bean>
	<bean id="user" class="cn.hncu.s3x.demo2.User">
		<property name="name" value="Jack" />
		<property name="age" value="20" />
		<property name="cat" ref="cat" />
		<property name="pets">
			<list>
				<value>Tom</value>
				<value>dog</value>
				<value>pig</value>
			</list>
		</property>
		<property name="map">
			<map>
				<entry key="name" value="中国">
				</entry>
			</map>
		</property>
		<property name="set">
			<set>
				<value>aaa</value>
				<value>bbb</value>
			</set>
		</property>
		<property name="objs">
			<array>
				<value>222</value>
				<ref bean="cat2" />
				<list>
					<ref bean="cat2" />
					<ref bean="cat" />
				</list>
				<bean class="cn.hncu.s3x.demo2.Cat">
					<property name="name" value="我的猫" />
				</bean>
			</array>
		</property>
		<property name="list">
			<list>
				<map>
					<entry key-ref="p" value-ref="cat"></entry>
					<entry value-ref="cat2">
						<key>
							<bean class="cn.hncu.s3x.domain.Person">
								<property name="name" value="王建安" />
								<property name="age" value="25" />
							</bean>
						</key>
					</entry>
				</map>
			</list>
		</property>
	</bean>
	<bean id="cat" class="cn.hncu.s3x.demo2.Cat">
		<property name="name" value="Tom猫" />
	</bean>
	<bean id="cat2" class="cn.hncu.s3x.demo2.Cat">
		<property name="name" value="黑猫" />
	</bean>
</beans>
这是Bean对象

package cn.hncu.s3x.demo2;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class User {
	private String name;
	private Integer age;
	private Cat cat;
	private List<String> pets;
	private Map<String,Object> map;
	private Set<String> set;
	private Object objs[];
	private List<Map<Object, Cat>> list;
	

	

	public List<Map<Object, Cat>> getList() {
		return list;
	}

	public void setList(List<Map<Object, Cat>> list) {
		this.list = list;
	}

	public Set<String> getSet() {
		return set;
	}

	public void setSet(Set<String> set) {
		this.set = set;
	}

	public Object[] getObjs() {
		return objs;
	}

	public void setObjs(Object[] objs) {
		this.objs = objs;
	}

	public Map<String, Object> getMap() {
		return map;
	}

	public void setMap(Map<String, Object> map) {
		this.map = map;
	}

	public List<String> getPets() {
		return pets;
	}

	public void setPets(List<String> pets) {
		this.pets = pets;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Cat getCat() {
		return cat;
	}

	public void setCat(Cat cat) {
		this.cat = cat;
	}
       @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", cat=" + cat
                + ", pets=" + pets + ", map=" + map + ", set=" + set
                + ", objs=" + Arrays.toString(objs) + ", list=" + list + "]";
    }
	
}



package cn.hncu.s3x.demo2;

public class Cat {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Cat [name=" + name + "]";
    }
    
}


package cn.hncu.s3x.domain;

public class Person {
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    
}

 

这是测试代码

package cn.hncu.s3x.demo2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo2 {
	@Test
	public void demo1(){
		ApplicationContext act=new ClassPathXmlApplicationContext("app2.xml");
		User user=act.getBean("user", User.class);
		System.out.println(user);
	}
}


四、Spring IOC 控制反转

     IoC(Inversion of Control)中文译为控制反转也可以叫做DIDependency Injection依赖注入)。

控制反转模式的基本概念是:不直接创建对象,但是xml配置文件中描述创建它们的方式。在工程中使用该Bean时由Spring容器创建Bean的实例。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。

第1步Spring注入(又称依赖注入DI):其目的是为其中bean的属性赋值

2:在配置文件中注入属性的初始值

五、Spring Bean的作用域

     Spring2.0之前bean只有2种作用域即:singleton(单例)non-singleton(也称prototype, Spring2.0以后,增加了sessionrequestglobal session三种专用于Web应用程序上下文的Bean

     因此,默认情况下Spring2.0现在有五种类型的Bean。当然,Spring2.0Bean的类型的设计进行了重构,并设计出灵活的Bean类型支持,理论上可以有无数多种类型的Bean,用户可以根据自己的需要,增加新的Bean类型,满足实际应用需求。

1singleton单实例

   当一个bean的作用域设置为singleton,那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singletoncache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例

<beanid="userdao"class="com.bean.UserDao"scope="singleton"/>

<beanid=" userdao" class="com.bean.UserDao"singleton="true"/> 

UserDaobean1=( UserDao)factory.getBean("userdao");

UserDaobean2=( UserDao)factory.getBean("userdao");

2prototype多实例  

    每个Spring容器中,一个bean对应多个实例. prototype作用域部署的bean每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当一个new的操作

<beanid="userdao"class="com.bean.UserDao"

                                                  scope="prototype"/>

<beanid=" userdao" class="com.bean.UserDao"

                                                    singleton="false"/> 

 UserDao bean1=(UserDao)factory.getBean("userdao");

 UserDao bean2=(UserDao)factory.getBean("userdao");

Bean1bean2的引用不相同。每次使用getBean()重新产生一个实例

3request   

     request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效

    <bean id="userdao"class="com.bean.UserDao"

                                                      scope="request"/>

4session    

      session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效.



Spring AOP编程

    切面( Aspect ): 简单的理解就是 把那些与核心业务无关的代码提取出来,进行封装成一个或几个模块用来处理那些附加的功能代码 。(如日志,事务,安全验证)我们把这个模块的作用理解为一个切面,其实 切面 就是我们写 一个类 ,这个类中的代码原来是在业务模块中完成的,现在单独成一个或几个类。在业务模块需要的时候才织入。
    连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。 在Spring AOP中,一个连接点总是代表一个方法的执行。通过声明一个JoinPoint类型的参数可以使通知(Advice)的主体部分获得连接点信息。 
    切入点(Pointcut):本质上是一个捕获连接点的结构。在AOP中,可以定义一个pointcut,来捕获相关方法的调用
     织入(Weaving):把切面(aspect连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象。这些可以在编译时,类加载时和运行时完成。Spring和其它纯Java AOP框架一样,在运行时完成织入。
     通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。
通知的类型:
    前置通知(Before advice:在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
    返回后通知(After returning advice:在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
    抛出异常后通知(After throwing advice:在方法抛出异常退出时执行的通知。
    后置通知(After finallyadvice:当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

     环绕通知(Around Advice包围一个连接点join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行



下面演示代码:

纯Java方式写AOP(拦截技术)

package cn.hncu.spring4x.aop;

import java.lang.reflect.Method;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;

import cn.hncu.spring4x.domain.Person;

public class AopDemo {
	@Test//纯Java的方式实现切面(拦截)技术
	public void demo1(){
		Person p=new Person();
		ProxyFactory factory=new ProxyFactory(); //该类的功能没有ProxyFactoryBean强
		factory.setTarget(p);//1 给代理工厂一个原型对象
		//切面 = 切点 + 通知
		//切点
		JdkRegexpMethodPointcut pointcut=new JdkRegexpMethodPointcut();
		pointcut.setPattern("cn.hncu.spring4x.domain.Person.run");
		//		pointcut.setPattern(".*run.*");ProxyFactory对setPattern无效
		Advice advice=new MethodInterceptor() {

			@Override
			public Object invoke(MethodInvocation invocation) throws Throwable {
				System.out.println("前面拦截");
				Object obj=invocation.proceed();
				System.out.println("后面拦截");
				return obj;
			}
		};
		//切面 = 切点 + 通知
		Advisor advisor=new DefaultPointcutAdvisor(pointcut, advice);

		factory.addAdvice(advice);

		Person p2=(Person) factory.getProxy();
//		p2.run();
//		p2.run(5);
		p2.say();
	}
	@Test//纯Java的方式实现切面(拦截)技术
	public void demo2(){
		ProxyFactoryBean factoryBean=new ProxyFactoryBean();
		factoryBean.setTarget(new Person());
		//切面 = 切点 + 通知
		//切点
		JdkRegexpMethodPointcut pointcut=new JdkRegexpMethodPointcut();
		pointcut.setPattern(".*run.*");

		//通知  前切面---不需要放行,原方法也能执行
		Advice beforeAdvice=new MethodBeforeAdvice() {
			@Override
			public void before(Method method, Object[] args, Object target)
					throws Throwable {
				System.out.println("beforeAdvice拦截");//正则表达式有效
			}
		};
		Advice afterReturning=new AfterReturningAdvice() {
			@Override
			public void afterReturning(Object returnValue, Method method,
					Object[] args, Object target) throws Throwable {
				System.out.println("afterReturning");
			}
		};

		Advice aroundAdvice=new MethodInterceptor() {

			public Object invoke(MethodInvocation invocation) throws Throwable {
				System.out.println("前面拦截");
				Object obj=invocation.proceed();
				System.out.println("后面拦截");
				return obj;
			}
		};
		Advisor advisor1=new DefaultPointcutAdvisor(pointcut, beforeAdvice);
		Advisor advisor2=new DefaultPointcutAdvisor(pointcut, afterReturning);
		Advisor advisor3=new DefaultPointcutAdvisor(pointcut, aroundAdvice);
		factoryBean.addAdvisors(advisor1,advisor2,advisor3);
		//2 给代理工厂一个切面 ---注意,添加的顺序的拦截动作执行的顺序是有关系的!!!
		//先加的切面,如果拦前面,就拦在最前面,如果拦后面,就拦在最后面.
		Person p = (Person) factoryBean.getObject(); //3 从代理工厂中获取一个代理后的对象
		//p.run();
		//p.run(0);
		p.say();
	}

}

下面演示5种理由配置文件AOP


通知:AroundAdvice.java

package cn.hncu.spring4x.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class AroundAdvice implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("前面拦拦....");
		Object resObj = invocation.proceed();//放行
		System.out.println("后面拦拦.....");
		return resObj;
	}

}



测试代码,

package cn.hncu.spring4x.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopXmlDemo {
	@Test//采用配置文件的方式使用切面拦截
	public void demo1(){
		ApplicationContext act=new ClassPathXmlApplicationContext("cn/hncu/spring4x/aop/1.xml");
		Cat cat=act.getBean("catProxide",Cat.class);//要从catProxide返回
		cat.run();
		cat.say();
		cat.run(6);
	}
	@Test//把切点和通知配置成 切面的内部bean
	public void demo2(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/spring4x/aop/2.xml");
		Cat cat = ctx.getBean("catProxide",Cat.class);
		cat.run();
		cat.say();
		cat.run(7);
	}
	@Test//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置
	public void demo3(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/spring4x/aop/3.xml");
		Cat cat = ctx.getBean("catProxide",Cat.class);
		cat.run();
		cat.say();
		cat.run(7);
	}
	@Test//自动代理
	public void demo4(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/spring4x/aop/4.xml");
		Cat cat = ctx.getBean(Cat.class);
		cat.run();
		cat.say();
		cat.run(7);
	}
	@Test//自己写的自动代理
	public void demo5(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/spring4x/aop/5.xml");
		Cat cat = ctx.getBean("cat",Cat.class);
//		cat.run();
//		cat.say();
//		cat.run(7);
	}
	
}
1.xml
<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<bean id="cat" class="cn.hncu.spring4x.aop.Cat"></bean>
	<!-- 切点 -->
	<bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
		<property name="pattern" value=".*run.*"></property>
	</bean>
	<!-- 通知 ,要自己写-->
	<bean id="advice" class="cn.hncu.spring4x.aop.AroundAdvice"></bean>
	
	<!-- 切面=切点+通知 -->
	<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice" ref="advice"></property>
		<property name="pointcut" ref="pointcut"></property>
	</bean>
	
	<bean id="catProxide" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="cat"></property>
		<property name="interceptorNames">
			<list>
				<value>advisor</value>
			</list>
		</property>
	</bean>
</beans>

2.xml

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<bean id="cat" class="cn.hncu.spring4x.aop.Cat"></bean>
	
	<!-- 切面=切点+通知 (把切点和通知写成内部bean)-->
	<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice">
			<bean class="cn.hncu.spring4x.aop.AroundAdvice"></bean>
		</property>
		<property name="pointcut">
			<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
			 <property name="patterns">
			 	<list>
			 		<value>.*run.*</value>
			 		<value>.*say.*</value>
			 	</list>
			 </property>
			 
			</bean>
		</property>
	</bean>
	
	<bean id="catProxide" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="cat"></property>
		<property name="interceptorNames">
			<list>
				<value>advisor</value>
			</list>
		</property>
	</bean>
</beans>


3.xml

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<bean id="cat" class="cn.hncu.spring4x.aop.Cat"></bean>

	<!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor -->
	<bean id="advisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice">
			<bean class="cn.hncu.spring4x.aop.AroundAdvice"></bean>
		</property>
		<property name="patterns">
			<list>
				<value>.*run.*</value>
			</list>
		</property>
	</bean>

	<bean id="catProxide" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="cat"></property>
		<property name="interceptorNames">
			<list>
				<value>advisor</value>
			</list>
		</property>
	</bean>
</beans>


4.xml

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<bean id="cat" class="cn.hncu.spring4x.aop.Cat"></bean>

	<!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor -->
	<bean id="advisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice">
			<bean class="cn.hncu.spring4x.aop.AroundAdvice"></bean>
		</property>
		<property name="patterns">
			<list>
				<value>.*run.*</value>
			</list>
		</property>
	</bean>
	<!-- 自动代理 -->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>


5.xml

<?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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<bean id="cat" class="cn.hncu.spring4x.aop.Cat"></bean>

	<!--//直接在切面bean中配置“切点的正则表达式”,省去“切点bean”的配置 用到这个类 org.springframework.aop.support.RegexpMethodPointcutAdvisor -->
	<bean id="advisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice">
			<bean class="cn.hncu.spring4x.aop.AroundAdvice"></bean>
		</property>
		<property name="patterns">
			<list>
				<value>.*run.*</value>
			</list>
		</property>
	</bean>
	<!-- 自动代理 -->
	
	<bean class="cn.hncu.spring4x.aop.MyAutoProxy"></bean>
</beans>

第五种方法,模拟自动代理

MyAutoProxy.java

package cn.hncu.spring4x.aop;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MyAutoProxy implements BeanPostProcessor,ApplicationContextAware{
	private ApplicationContext applicationContext;
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext=applicationContext;//保证是同一个容器

	}
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println(bean+"postProcessBeforeInitialization");
		return bean; //直接放行(一定要)
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println(bean+"postProcessAfterInitialization");
		ProxyFactoryBean factoryBean=new ProxyFactoryBean();
		factoryBean.setTarget(bean);
		Advisor advisor=applicationContext.getBean("advisor", Advisor.class);
		factoryBean.addAdvisor(advisor);
		return factoryBean.getObject();
	}


	
}









  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值