面向切面的编程(AOP)

面向切面的编程(AOP)

目前我对面向对象的理解是:
动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程
可以和面向对象的编程做对比,具体百度百科就描述的不错,所以我就不赘述了。
而面向对象的编程是通过动态代理实现的。
下面通过一个简单示例通了解一下面向对象编程的思想。

一.面向切面编程的引入

1.1创建Person类

package edu.xatu;

import org.springframework.stereotype.Repository;

@Repository
public class Person implements PersonInterface {
    public void travel (){
        System.out.println ("旅游");
    }

    public void work (){
        System.out.println ("上班");
    }

    public void visit (){
        System.out.println ("探亲");
    }
}

@Repository注解的作用是实例化对象Person,来自lombok插件

@Controller 主要用到web层

@Service 服务service层

@Repository 数据访问层 dao层

1.1.2 @Autowired、@Qualifier(“ser”)、@Resource

  • 首先所有装配的对象要先实例化到工厂当中
  • 其次可以通过三个注解实现依赖注入
  • @Autowired 根据类型装配
  • @Qualifier(“ser”) 和@Autowired结合使用,根据名称进行装配
  • @Resource相当中@Autowired加@Qualifier(“ser”),即可根据类型进行装配,也可以根据名称进行装配

1.2生成person的接口PersonInterface

package edu.xatu;

public interface PersonInterface {
    void travel ();

    void work ();

    void visit ();
}

1.3创建personService

package edu.xatu;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class PersonService {
    
    @Resource(name = "sss")
    private Ser ser;
    @Resource
    private Student student;
    @Resource
    private Person person;
    public void service(){
        ser.getdress ();
        ser.eatbreakfirst ();
        person.travel ();

        ser.getdress ();
        ser.eatbreakfirst ();
        person.visit ();

        ser.getdress ();
        ser.eatbreakfirst ();
        person.work ();
        student.havelesson ();
    }
}

1.4创建Ser类

package edu.xatu;

import org.springframework.stereotype.Component;

@Component("sss")
public class Ser {
    public void getdress(){
        System.out.println ("穿衣服");
    }
    public void eatbreakfirst(){
        System.out.println ("吃早饭");
    }
}

1.5创建Student类

package edu.xatu;

import org.springframework.stereotype.Component;

@Component
public class Student implements StudentInterface {
    public void havelesson (){
        System.out.println ("上课");
    }
}

1.6生成Student接口StudentInterface

package edu.xatu;

public interface StudentInterface {
    void havelesson ();
}

1.7测试

package edu.xatu;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main (String[] args) {
        //创建工厂
        BeanFactory factory = new ClassPathXmlApplicationContext ( "applicationContext.xml" );
        PersonService personService = factory.getBean ( PersonService.class );
        personService.service ();
    }
}

1.8配置文件applicationContext.xml添加内容:

<context:component-scan base-package="edu.xatu"/>

component-scan是component-scanner的缩写,表示组件扫描,整体意思是从包edu.xatu开始逐一扫描类。

1.9测试结果:

在这里插入图片描述

由1.3中的service方法可知,相同代码重复出现:

ser.getdress ();
ser.eatbreakfirst ();

为了避免这种动作代码重复出现,优化代码风格,采取类似于Filter(过滤器)这种想法编程,也就是面向切面的编程,虽然不全面,意思到了就行。

二.首先引入动态代理

2.1创建动态代理类

package edu.xatu;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy implements InvocationHandler {

    private Object target;  //目标对象
    public DynamicProxy(Object target){
        this.target = target;
    }
    //动态代理所执行的代码如下
    public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
        //因为在这儿没法注入,所以只能new
        Ser ser = new Ser ();
        ser.getdress ();
        ser.eatbreakfirst ();
        return method.invoke ( target,args );
    }

    public Object createProxy(){
        //创建代理
       return Proxy.newProxyInstance ( this.getClass ().getClassLoader (),
                                target.getClass ().getInterfaces (),
                                this);//this.getClass ().getClassLoader ()类加载器
    }
}

2.2修改PersonInterface类:

package edu.xatu;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class PersonService {

    private PersonInterface person = (PersonInterface) new DynamicProxy (new Person () ).createProxy (); //注入的是person对象
    private StudentInterface student = (StudentInterface) new DynamicProxy ( new Student () ).createProxy ();
    
    public void service(){
        student.havelesson ();
        person.travel ();
        person.visit ();
        person.work ();
    }
}

其他类注解删掉即可

2.3测试结果:

在这里插入图片描述

发布了101 篇原创文章 · 获赞 49 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Austin_/article/details/100807771
今日推荐