Spring的IOC和AOP

一.Sqring IOC

1.spring IOC 容器表格

                

1.2初始化Spring上下文容器(IOC)        

ApplicationContext ac=new ClassXmlPathApplicationContext("spring.xml");

二.Spring AOP

        1.AOP中关键性概念:
                连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.

        2.AOP工具类:

                2.1org.springframework.aop.framework.ProxyFactoryBean用来创建一个代理对象,在一般情况下它需要注入以下三个属性:

                        proxyInterfaces:代理应该实现的接口列表(List)
                        interceptorNames:需要应用到目标对象上的通知Bean的名字。(List)
                        target:目标对象 (Object)

        3.AOP三种通知:

             3.1:前置通知(org.springframework.aop.MethodBeforeAdvice):在连接点之前执行的通知()  

             3.2:后置通知(org.springframework.aop.AfterReturningAdvice):在连接点正常完成后执行的通知

             3.3:环绕通知(org.aopalliance.intercept.MethodInterceptor):包围一个连接点的通知,最大特点是可以修改返回值,由于它在方法前后都加入了自己的逻辑代码,因此功能异常强大。
             它通过MethodInvocation.proceed()来调用目标方法(甚至可以不调用,这样目标方法就不会执行)

        前置通知案例:在购书系统当中使用AOP方式实现日志系统

        先创建一个通用的接口和实现类

/**
 * 目标接口
 */
public interface IBookBiz {
	// 购书
	public boolean buy(String userName, String bookName, Double price);
 
	// 发表书评
	public void comment(String userName, String comments);
}

    

/**
 * 目标实现类
 */
public class BookBizImpl implements IBookBiz {
 
	public BookBizImpl() {
		super();
	}
 
	public boolean buy(String userName, String bookName, Double price) {
		// 通过控制台的输出方式模拟购书
		if (null == price || price <= 0) {
			throw new PriceException("book price exception");
		}
		System.out.println(userName + " buy " + bookName + ", spend " + price);
		return true;
	}
 
	public void comment(String userName, String comments) {
		// 通过控制台的输出方式模拟发表书评
		System.out.println(userName + " say:" + comments);
	}
 
}

/**
 * 前置通知,用于目标方法被调用之前进行日志收集
 */
public class BeforeAdvice implements MethodBeforeAdvice {
    /**
     *
     * @param method 目标方法
     * @param args  目标方法所执行的参数
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] args, Object target)
            throws Throwable {
        //获取被调用的方法名
        String methodName = method.getName();
        //获取目标方法的类的全路径名
        String className = target.getClass().getName();
 
        System.out.println("[前置通知]"+className+"."+methodName+
                "执行参数:"+ Arrays.toString(args));
 
    }
}


<!--代理=通知+目标 只有完整的代理对象才具有AOP特性,而AOP代码是写在通知中-->
        <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!--通知-->
            <property name="interceptorNames">
                <list>
                    <!--前置通知-->
                    <value>beforeAdvice</value>
                    <!--...此处加多个通知-->
                </list>
            </property>
            <!--目标-->
            <property name="target">
                <ref bean="BookBizTarget"/>
            </property>
 
 
            <!--定义代理对象实现的接口-->
            <property name="proxyInterfaces">
                    <list>
                        <value>biz.IBookBiz</value>
                    </list>
            </property>
        </bean>

开始初始化spring.xml上下文并执行目标方法

//1.初始化Spring上下文容器(IOC)
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
IBookBiz proxy = ac.getBean("proxy", IBookBiz.class);
//调用buy和comment方法时,会将前置通知应用到目标方法上得到代理对象
proxy.buy("李四","西游记",200d);
proxy.comment("李四","好看,名著");

IBookBiz bookBiz1=new BookBizImpl();
 
IBookBiz bookBiz2=new Proxy();

效果:

【前置通知】biz.BookBizImpl.buy执行参数[李四, 西游记, 200.0]
李四 buy 西游记, spend 200.0
【前置通知】biz.BookBizImpl.comment执行参数[李四, 好]
李四 say:好

 后置通知案例

        

/**
 * 后置通知
 */
public class AfterAdvice implements AfterReturningAdvice {
 
    /**
     *
     * @param returnValue  目标方法的返回值
     * @param method       目标方法
     * @param args         目标方法的执行参数
     * @param target       目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method,
                               Object[] args, Object target) throws Throwable {
        //获取目标方法名
        String methodName = method.getName();
        //获取目标方法的类的全路径名
        String className = target.getClass().getName();
        System.out.println("[后置通知]"+className+"."+methodName+
                "执行参数"+ Arrays.toString(args)+"返回值:"+returnValue);
    }
}
<!--代理=通知+目标 只有完整的代理对象才具有AOP特性,而AOP代码是写在通知中-->
        <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!--通知-->
            <property name="interceptorNames">
                <list>
                   <!--前置通知-->
                    <!--<value>beforeAdvice</value>-->
                    <!--后置通知-->
                   <value>afterAdvice</value>
                    <!--...此处加多个通知-->
                </list>
            </property>
            <!--目标-->
            <property name="target">
                <ref bean="BookBizTarget"/>
            </property>
 
 
            <!--定义代理对象实现的接口-->
            <property name="proxyInterfaces">
                    <list>
                        <value>biz.IBookBiz</value>
                    </list>
            </property>
        </bean>

//1.初始化Spring上下文容器(IOC)
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
IBookBiz proxy = ac.getBean("proxy", IBookBiz.class);
//调用buy和comment方法时,会将前置通知应用到目标方法上得到代理对象
proxy.buy("李四","西游记",200d);
proxy.comment("李四","好看,名著");

 李四 buy 西游记, spend 200d
【后置通知】biz.BookBizImpl.buy执行参数[李四, 西游记, 200.0]返回值true
李四 say:好看

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值