Spring学习笔记_02

4 篇文章 0 订阅

6.通过javaConfig配置Spring

  • 完全通过JavaConfig来配置Spring
  1. pojo包
  • 创建一个实体类,并使用@Component注解,将该类注册到Spring容器中
//使用该注解,将User类注册到Spring容器,装配Bean
@Component
public class User {
    private String name;

    public String getName() {
        return name;
    }

    @Value("晴明")
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

  1. config包
  • 使用@Configuration将该配置类注册到Spring容器中
//使用这个注解后,该类也会被注册到Spring容器中,@Configuration也属于一个@Component
//使用@Configuration代表这是一个配置类,类似applicationContext.xml
@Configuration
public class EicomaConfig {

    //@Bean  该注解可注册一个Bean
    //该方法的名字,相当于xml中bean的id
    //该方法的返回值,相当于xml中bean的class
    @Bean
    public User getUser(){
        //返回要注入到Spring容器中的对象
        return new User();
    }
}

  • 使用@Bean将要注册的类注册到Spring容器中
//@Bean  该注解可注册一个Bean
    //该方法的名字,相当于xml中bean的id
    //该方法的返回值,相当于xml中bean的class
    @Bean
    public User getUser(){
        //返回要注入到Spring容器中的对象
        return new User();
    }



  • 使用@ComponentScan(“com.eicoma.pojo”)注册配置类,和@Component相似
//@ComponentScan("com.eicoma.pojo")的功能和Configuration一致
@ComponentScan("com.eicoma.pojo")
public class EicomaConfig {

    //@Bean  该注解可注册一个Bean
    //该方法的名字,相当于xml中bean的id
    //该方法的返回值,相当于xml中bean的class
    @Bean
    public User getUser(){
        //返回要注入到Spring容器中的对象
        return new User();
    }
}

7.代理模式

  • 代理模式
    • 静态代理
    • 动态代理

7.1静态代理

  • 角色分类

    • 抽象角色(用接口或抽象类表示)
    public interface Rent {
        public  void rent();
    }
    
    • 真实角色(被代理的角色)
    public class Host implements Rent{
    
        public void rent() {
            //房东只需考虑交出房子,其他的一切交给代理
            System.out.println("房东出租房子!");
        }
    }
    
    • 代理
    public class Proxy implements Rent{
        private Host host;
    
        public Proxy(){
    
        }
    
        public Proxy(Host host){
            this.host = host;
        }
    
        //代理租房的一切动作
        public void rent() {
            host.rent();
            seeHose();
            qianHeTong();
            shouFei();
        }
    
        //看房
        private void seeHose(){
            System.out.println("看房子!");
        }
    
        //签合同
        private void qianHeTong(){
            System.out.println("签合同!");
        }
    
        //收费
        private void shouFei(){
            System.out.println("收取中介费!");
        }
    }
    
    • 客户(访问代理)
    public class Client {
        public static void main(String[] args) {
            Host host = new Host();
            //代理帮助房东出租房子
            Proxy proxy = new Proxy(host);
    
            //租客直接面代理,无需直接面对房东
            proxy.rent();
        }
    }
    
  • 代理模式优点

    • 使真实角色不必关注公共的业务
    • 公共业务交给代理,实现业务的分工
    • 方便公共业务扩展
  • 代理模式缺点

    • 每一种类型的真实角色,就会产生一种对应的代理!会导致代码量提升!
加深理解
  • 当需要扩展原有真实角色类的功能时,可以使用代理

    • 抽象角色

    该接口有四个功能需求

    public interface UserService {
        public void add();
        public void delete();
        public void update();
        public void query();
    }
    
    • 真实角色

    实现接口功能

    public class UserServiceImpl implements UserService{
    
        public void add() {
            System.out.println("添加了一个用户!");
        }
    
        public void delete() {
            System.out.println("删除了一个用户!");
        }
    
        public void update() {
            System.out.println("修改了一个用户!");
        }
    
        public void query() {
            System.out.println("查询了一个用户!");
        }
    }
    
    • 代理

    增加需求,在原有功能实现时额外输出日志信息

    public class UserServiceProxy implements UserService{
    
        private UserServiceImpl userService;
    
        public void setUserService(UserServiceImpl userService){
            this.userService = userService;
        }
    
        public void add() {
            log("add");
            userService.add();
        }
    
        public void delete() {
            log("delete");
            userService.delete();
        }
    
        public void update() {
            log("update");
            userService.update();
        }
    
        public void query() {
            log("query");
            userService.query();
        }
    
        private void log(String msg){
            System.out.println("当前使用了"+msg+"方法");
        }
    }
    
    • 客户

    引入真实角色对象及代理对象,调用代理对象的方法

    public class Client {
        public static void main(String[] args) {
    //        UserService userService = new UserServiceImpl();
    //        userService.add();
            UserServiceImpl userService = new UserServiceImpl();
            UserServiceProxy userServiceProxy = new UserServiceProxy();
    
            userServiceProxy.setUserService( userService);
    
            userServiceProxy.add();
        }
    }
    
  • AOP

不改动原有代码的前提下,通过代理的方式扩展功能!—【面向切面编程】

7.2动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的!
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口:JDK动态代理
    • 基于类:cglib
    • java字节码实现:javasist

要了解两个类:

  • Proxy:代理

  • InvocationHandler:调用处理程序

动态代理好处:

  • 使真实角色不必关注公共的业务

  • 公共业务交给代理,实现业务的分工

  • 方便公共业务扩展

  • **动态代理类代理的是一个接口!!**代表可代理一类业务!!只要是实现了该接口的实现类,均可以由此动态生成代理,无需重复编写静态代理!!

    而静态代理代理的仅仅只是一个接口的实现类(真实角色),因此导致每有一个接口实现类,就需要再写一个静态代理!

代码示例

  • 抽象角色
public interface UserService2 {
    public void add();
    public void delete();
    public void update();
    public void query();
}
  • 真实角色
public class UserService2Impl implements UserService2 {

    public void add() {
        System.out.println("添加了一个用户!");
    }

    public void delete() {
        System.out.println("删除了一个用户!");
    }

    public void update() {
        System.out.println("修改了一个用户!");
    }

    public void query() {
        System.out.println("查询了一个用户!");
    }
}
  • 动态代理类
    • proxy:生成动态代理对象
    • InvocationHandler:调用处理程序,返回结果(返回了真实角色+扩展的方法的结果)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationHandler implements InvocationHandler {

    //UserService2 userService2可替换为Object target(通用类型)
    private UserService2 userService2;

    public void setUserService2(UserService2 userService2) {
        this.userService2 = userService2;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),userService2.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //log()为扩展的方法
        //method.getName()返回了当前在Client层所调用的方法的名称
        log(method.getName());
        //这个invoke()返回了接口实现类对象UserService2Impl内部方法的所有结果----【重点!!!】
        Object result = method.invoke(userService2,args);
        return result;
    }

    public void log(String msg){
        System.out.println("当前使用了"+msg+"方法");
    }
}

  • 客户
public class Client {
    public static void main(String[] args) {
        //获取接口对象(抽象角色)
        UserService2 userService2 = new UserService2Impl();
        //获取动态代理生成器类对象
        ProxyInvocationHandler pih = new ProxyInvocationHandler();

        //将接口对象传入pih对象中
        pih.setUserService2(userService2);

        //动态获取Proxy代理
        //此处getProxy()返回的是Object对象,需要强转
        UserService2 proxy= (UserService2) pih.getProxy();

        //现在就能通过proxy代理调用方法啦!
        proxy.add();
    }
}

注:动态代理和静态代理最大的区别

动态代理通过反射,使代理从单纯代理某一个接口实现类,跨越到代理某一个接口!

从而使实现同一个接口的实现类均可由该动态代理进行代理!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值