一个接口两个实现类中Autowired注解的使用/代理

1.一个接口两个实现

@Autowired注解在注入的过程中有两种方式:

(1)ByType和ByName,ByType在一个接口两个实现的情况下是绝对找不到的,所以只能采用ByName的方式

2.静态代理

2.1使用静态代理的原因

在这里插入图片描述

2.2静态代理的原理及使用

1.接口 2.代理 3.目标对象

在这里插入图片描述

 接口代码:

package com.jt.mapper;

import com.jt.pojo.User;

public interface UserDao {
    void addUser(User user);
}

目标代码:

package com.jt.service;

import com.jt.mapper.UserDao;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("target")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    public void addUser(User user) {

        userDao.addUser(user);
    }
}

 代理代码块:

package com.jt.proxy;

import com.jt.mapper.UserDao;
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class StaticProxy implements UserService {

    @Autowired
    private UserService target;
    @Override
    public void addUser(User user) {
        try {
            System.out.println("事物开始");
            target.addUser(user);
            System.out.println("事务结束");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("事务回滚");
        }
    }
}

测试代码:一定要按名字调用否则会报错

 2.3静态代理的弊端

1).静态代理只针对于某个接口 不能实现所有接口的代理 实用性较差

在这里插入图片描述

 2).静态代理中所有的方法,都需要手动的添加事务开始/事务提交代码 代码冗余 不够简洁.

在这里插入图片描述

3动态代理

原理:利用一个工厂动态的目标对象创建代理

需要注意的知识:匿名内部类 new invocationhandler

1.ClassLoader loader, 类加载器(获取目标对象的Class)
2.类<?>[] interfaces,  JDK代理要求 必须有接口,java中可以多实现
3.InvocationHandler h  对目标方法进行扩展

代码中:

1.target目标对象
2.proxy代理对象 带目标对象的方法进行扩展

此代码块创建了一个代理对象:

Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {

package com.jt.proxy;

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

//能否利用一个工厂动态为目标对象创建代理
public class JDKProxyFactory {

    //要求用户传递目标对象
    //关于匿名内部类用法说明:  匿名内部类引用外部参数 要求参数必须final修饰
    public static Object getProxy(final Object target){
        //1.调用java API实现动态代理
        /**
         *  参数分析: 3个参数
         *      1.ClassLoader loader, 类加载器(获取目标对象的Class)
         *      2.类<?>[] interfaces,  JDK代理要求 必须有接口
         *                             java中可以多实现
         *      3.InvocationHandler h  对目标方法进行扩展
         */
        //1.获取类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2.获取接口数组
        Class[] interfaces = target.getClass().getInterfaces();
        //3.通过动态代理创建对象
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {

            //invoke方法: 代理对象调用方法时invoke执行,扩展方法的编辑位置
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //proxy: 代理对象本身
                //method: 用户调用的方法对象
                //args:   用户调用方法的参数

                // result 标识目标方法执行的返回值
                Object result = null;
                try {
                    //添加事务的控制
                    System.out.println("事务开始");
                    //执行目标方法
                    // target真实的目标对象,method方法对象,args方法参数
                    result = method.invoke(target,args);
                    System.out.println("事务提交");
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("事务回滚");
                }
                return result;
            }
        });

        return proxy;
    }

}

动态代理优点

1可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
2公共业务就交给代理角色,实现了业务分工
3公共业务发生扩展的时候,方便集中管理
4一个动态代理类代理的是一个接口,一般就是对应的一类业务(多个类实现同一个接口,只要重写方法,客户端可以通过修改代理的真实对象来实现动态的代理)
5多个房东同时卖房,他们的房子信息不一样,如果采用静态代理,需要为他们各自写一个代理类,就十分麻烦。我们可以采用动态代理的方法,让这些房东同时实现一个接口(Rent),这样我们在客户类只需要修改代理的真实对象,就可以得到每个房东各自的房子信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值