Spring之IOC与AOP

IOC与AOP

IOC:控制反转,将实例的生命周期交由Spring框架管理,可通过XML文件定义需要管理的类(<bean>标签定义、FactoryBean定义、组件注解扫描) 

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

    <!--开启组件扫描-->
    <context:component-scan base-package="com.jason.lee.ioc" use-default-filters="false">
        <!--扫描筛选-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    </context:component-scan>

    <!--构造器注入 参数默认顺序对应  scope作用域为单例,容器初始化时创建-->
    <!--1、构造器  2、依赖注入  3、初始化init 4、使用  5、销毁destroy-->
    <bean id="example01" class="com.jason.lee.ioc.Example" scope="singleton"
          init-method="init" destroy-method="destroy">
        <constructor-arg value="1"/>
        <constructor-arg value="example01" index="1" type="java.lang.String"/>
    </bean>

    <!--Setter属性注入 存在无参构造函数和对应属性的set方法-->
    <bean id="example02" class="com.jason.lee.ioc.Example">
        <property name="id" value="2"/>
        <property name="name" value="example02"/>
    </bean>

    <!--Setter属性注入 p命名空间简化写法-->
    <bean id="example03" class="com.jason.lee.ioc.Example" p:id="3" p:name="example03"/>

    <bean id="test01" class="com.jason.lee.ioc.MyBean">
        <property name="id" value="1"/>
        <property name="name" value="test01"/>
        <!--ref引用外部bean-->
        <property name="example" ref="example01"/>
    </bean>

    <bean id="example04" class="com.jason.lee.ioc.Example">
        <constructor-arg value="4"/>
        <constructor-arg value="example04" index="1" type="java.lang.String"/>
        <!--注入集合-->
        <property name="list">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>
        <property name="array">
            <array>
                <value>4</value>
                <value>5</value>
            </array>
        </property>
        <property name="map">
            <map>
                <entry>
                    <key>
                        <value>key</value>
                    </key>
                    <value>value</value>
                </entry>
            </map>
        </property>
    </bean>

    <bean id="example05" class="com.jason.lee.ioc.Example">
        <property name="list" ref="list"/>
    </bean>

    <!--集合bean-->
    <util:list id="list">
        <value>6</value>
        <value>7</value>
        <value>8</value>
    </util:list>

    <bean id="test02" class="com.jason.lee.ioc.MyBean">
        <property name="id" value="2"/>
        <property name="name" value="test02"/>
        <property name="example" ref="example01"/>
        <!--通过级联属性设置值-->
        <property name="example.id" value="0"/>
        <property name="example.name" value="xxx"/>
    </bean>

    <bean id="test03" class="com.jason.lee.ioc.MyBean">
        <property name="id" value="3"/>
        <property name="name" value="test03"/>
        <property name="example">
            <!--内部bean-->
            <bean class="com.jason.lee.ioc.Example">
                <property name="id" value="0"/>
                <property name="name" value="xxx"/>
            </bean>
        </property>
    </bean>

    <!--工厂-->
    <bean id="myFactory" class="com.jason.lee.ioc.MyFactoryBean"/>

    <!--自动注入-->
    <bean id="employee" class="com.jason.lee.ioc.Employee" autowire="byName">
        <property name="id" value="1"/>
        <property name="name" value="employee"/>
    </bean>

    <bean id="car" class="com.jason.lee.ioc.Car" p:brand="Benz" p:price="100000"/>

</beans>
public class MyFactoryBean implements FactoryBean<Car> {
    @Override
    public Car getObject() throws Exception {
        Car car = new Car();
        car.setBrand("BMW");
        car.setPrice(2000000D);
        return car;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}
@Component
public class Bean {

    @Override
    public String toString() {
        return "Bean to String";
    }
}

AOP:面向切面编程,利用动态代理实现业务逻辑与横切逻辑解耦

1、业务接口与实现类 

public interface MathIntf {
    int add(int i, int j);

    int div(int i, int j);
}


@Component("mathImpl")
public class MathIntfImpl implements MathIntf {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        System.out.println(result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i/j;
        System.out.println(result);
        return result;
    }
}

2、AOP实现

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

    <context:component-scan base-package="com.jason.lee.aop.xml"/>

    <aop:config>
        <!--切面 = 切点 + 通知-->
        <aop:aspect id="myAspect" ref="myLogger">
            <!--切点:何处-->
            <aop:pointcut id="myPointcut" expression="execution(* com.jason.lee.aop.xml.*.*(..))"/>
            <!--<aop:before method="before" pointcut="execution(* com.jason.lee.spring-aop-annotation.xml.*.*(..))"/>-->
            <!--通知:何时、内容-->
            <aop:before method="before" pointcut-ref="myPointcut"/>
            <aop:after method="after" pointcut-ref="myPointcut"/>
        </aop:aspect>
    </aop:config>

</beans>
@Component
public class MyLogger {
    public static void before() {
        System.out.println("前置通知");
    }

    public static void after() {
        System.out.println("后置通知");
    }
}

     2.2、注解方式

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

    <context:component-scan base-package="com.jason.lee.aop.annotation"/>

    <!--开启aspectj的自动代理功能-->
    <aop:aspectj-autoproxy/>

</beans>
@Component
@Aspect  //标注当前类为切面
@Order(value = 1)  //定义切面作用的优先级 【值越小优先级越高】
public class MyAspect {


    //定义公共切入点
    @Pointcut(value = "execution(* com.jason.lee.aop.annotation.*.*(..))")
    public void pointCut(){}


    /**
     * @Before 将方法指定为前置通知  【方法执行前】
     * 必须设置value,其值为切入点表达式(定位被作用的位置——连接点)
     * joinPoint 获取连接点信息
     */
    //@Before(value = "execution(public int com.jason.lee.aop.annotation.MathIntfImpl.add(int,int))")
    //   *    com.jason.lee.aop.*.*(..)
    //   任意访问修饰符    任意类 任意方法 任意参数
    @Before(value = "execution(* com.jason.lee.aop.annotation.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        String name = joinPoint.getSignature().getName();
        System.out.println("前置通知——Method: " + name + ", Args: " + Arrays.toString(args));
    }


    /**
     * 后置通知相当于作用在finally语句块 即无论是否异常均执行后置逻辑
     * @param joinPoint
     */
    @After(value = "pointCut()")
    public void afterMethod(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知——Method: " + name + ", Args: " + Arrays.toString(args));
    }


    /**
     * 返回通知  【方法执行后】
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "execution(* com.jason.lee.aop.annotation.*.*(..))",returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint,Object result) {
        String name = joinPoint.getSignature().getName();
        System.out.println("返回通知——Method: " + name + ", Result: " + result);
    }


    @AfterThrowing(value = "execution(* com.jason.lee.aop.annotation.*.*(..))",throwing = "exception")
    public void afterThrowingMethod(JoinPoint joinPoint,Exception exception) {
        String name = joinPoint.getSignature().getName();
        System.out.println("异常通知——Method: " + name + ", Exception: " + exception);
    }


    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     */
    @Around(value = "execution(* com.jason.lee.aop.annotation.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) {
        Object result;
        try {
            // 前置通知
            System.out.println("前置通知");
            result = proceedingJoinPoint.proceed(); // 执行方法
            // 返回通知
            System.out.println("返回通知");
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            // 异常通知
            System.out.println("异常通知");
        } finally {
            // 后置通知
            System.out.println("后置通知");
        }
        return -1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值