2022.5.29 使用java配置spring 与代理模式

9、使用java配置spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!

JavaConfig 是Spring的一个子项目,在Spring 4之后,它成为了一个核心功能!

 

 

User

 1 package com.xing.pojo;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.stereotype.Component;
 5 
 6 //这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
 7 @Component
 8 public class User {
 9     private String name;
10 
11     public String getName() {
12         return name;
13     }
14 
15     @Value("小明")
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     @Override
21     public String toString() {
22         return "User{" +
23                 "name='" + name + '\'' +
24                 '}';
25     }
26 }

 

MyConfig2

1 package com.xing.config;
2 
3 import org.springframework.context.annotation.Configuration;
4 
5 @Configuration
6 public class MyConfig2 {
7 
8 }

 

MyConfig

 1 package com.xing.config;
 2 
 3 import com.xing.pojo.User;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.ComponentScan;
 6 import org.springframework.context.annotation.Configuration;
 7 import org.springframework.context.annotation.Import;
 8 
 9 //Configuration代表这是一个配置类,就和我们之前看的beans.xmL一样
10 //这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@Component
11 @Configuration
12 @ComponentScan("com.xing.pojo") //扫描包
13 @Import(MyConfig2.class)  //相当于合并另一个配置文件
14 public class MyConfig {
15 
16     //注册一个bean .就相当于我们之前写的一个bean标签
17     //这个方法的名字,就相当了 bean标签中的id属性
18     //这个方法的返回值。就相当bean标签中的cLass属性
19 
20 
21     @Bean
22     public User getUser() {
23         return new User();//就是返回要注入到bean的对象!
24 
25     }
26 }

 

test

 1 import com.xing.config.MyConfig;
 2 import com.xing.pojo.User;
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 5 
 6 public class MyTest {
 7     public static void main(String[] args) {
 8         //纯注解方式
 9         //如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的cLass对象加载!
10         ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
11         //                                    参数为Bean注解下的方法名
12         User getUser = (User) context.getBean("getUser");
13         System.out.println(getUser.getName());
14     }
15 }

 

 

 

10、代理模式

为什么要学习代理模式?因为这就是SpringAOP的底层!【SpringAOP和SpringMvC】

代理模式的分类:

  • 静态代理

  • 动态代理

 

 

10.1、静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决

  • 真实角色︰被代理的角色

  • 代理角色︰代理真实角色,代理真实角色后,我们一般会做一些附属操作

  • 客户:访问代理对象的人!

代码步骤:

 

 

1.接口

1 package com.xing.demo01;
2 
3 //租房:
4 public interface Zufang {
5     void rent();
6 }

 

2.真实角色

 1 package com.xing.demo01;
 2 
 3 //房东:真实角色
 4 public class Fangdong implements Zufang{
 5     @Override
 6     public void rent() {
 7         System.out.println("房东出租房子");
 8     }
 9 
10 }

 

3.代理角色

 1 package com.xing.demo01;
 2 
 3 public class Zhongjie implements Zufang{
 4     private Fangdong fangdong;
 5 
 6     public Zhongjie() {
 7     }
 8 
 9     public Zhongjie(Fangdong fangdong) {
10         this.fangdong = fangdong;
11     }
12 
13     @Override
14     public void rent() {
15         seeHouse();
16         fangdong.rent();
17         fare();
18     }
19 
20     public void seeHouse() {
21         System.out.println("中介带你看房");
22     }
23     public void fare() {
24         System.out.println("收中介费");
25     }
26 }

 

4.客户端访问代理角色

 1 package com.xing.demo01;
 2 
 3 //租客(我):
 4 public class Zuke {
 5     public static void main(String[] args) {
 6         Fangdong fangdong = new Fangdong();
 7 
 8         //代理,//代理,中介帮房东租房子,但是呢?代理角色一般会有一些附属操作!│
 9         Zhongjie zhongjie = new Zhongjie(fangdong);
10         //你不用面对房东,直接找中介租房即可
11         zhongjie.rent();
12     }
13 }

 

代理模式的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务

  • 公共也就就交给代理角色!实现了业务的分工!

  • 公共业务发生扩展的时候,方便集中管理!

缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率会变低~

练习

在调用每个业务的前面增加一个日志,表明使用了什么业务(不修改原来代码(真实角色与业务的代码)增加代理,在代理中修改代码)

业务

1 package com.xing.demo02;
2 
3 public interface UserService {
4     void add();
5     void delete();
6     void update();
7     void query();
8 
9 }

 

真实角色

 1 package com.xing.demo02;
 2 
 3 public class UserServiceImpl implements UserService{
 4     @Override
 5     public void add() {
 6         System.out.println("增加一个用户");
 7     }
 8 
 9     @Override
10     public void delete() {
11         System.out.println("删除一个用户");
12     }
13 
14     @Override
15     public void update() {
16         System.out.println("修改一个用户");
17     }
18 
19     @Override
20     public void query() {
21         System.out.println("查询一个用户");
22     }
23 }

 

代理角色

 1 package com.xing.demo02;
 2 
 3 public class UserServiceProxy implements UserService{
 4     private UserServiceImpl userService;
 5 
 6     public void setUserService(UserServiceImpl userService) {
 7         this.userService = userService;
 8     }
 9 
10     @Override
11     public void add() {
12         log("add");
13         userService.add();
14     }
15 
16     @Override
17     public void delete() {
18         log("delete");
19         userService.delete();
20     }
21 
22     @Override
23     public void update() {
24         log("update");
25         userService.update();
26     }
27 
28     @Override
29     public void query() {
30         log("query");
31         userService.query();
32     }
33 
34     //日志方法
35     public void log(String msg){
36         System.out.println("使用了"+msg+"方法");
37     }
38 
39 }

 

客户端访问

 1 package com.xing.demo02;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         UserServiceImpl userService = new UserServiceImpl();
 6 
 7         UserServiceProxy proxy = new UserServiceProxy();
 8         //代理真实角色
 9         proxy.setUserService(userService);
10         proxy.add();
11         proxy.query();
12 
13     }
14 }

 

 

 

AOP:

 

 

10.2、动态代理

  • 动态代理和静态代理角色一样

  • 动态代理的代理类是动态生成的,不是我们直接写好的!

  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理。

    • 基于接口---JDK动态代理

    • 基于类:cglib

    • java字节码实现 : javasist

需要了解两个类: Proxy:代理,InvocationHandler:调用处理程序

UserService

1 package com.xing.demo04;
2 
3 public interface UserService {
4     void add();
5     void delete();
6     void update();
7     void query();
8 
9 }

 

UserServiceImpl

 1 package com.xing.demo04;
 2 
 3 public class UserServiceImpl implements UserService {
 4     @Override
 5     public void add() {
 6         System.out.println("增加一个用户");
 7     }
 8 
 9     @Override
10     public void delete() {
11         System.out.println("删除一个用户");
12     }
13 
14     @Override
15     public void update() {
16         System.out.println("修改一个用户");
17     }
18 
19     @Override
20     public void query() {
21         System.out.println("查询一个用户");
22     }
23 }

 

ProxyInvocationHandler

 1 package com.xing.demo04;
 2 
 3 import com.xing.demo03.Rent;
 4 
 5 import java.lang.reflect.InvocationHandler;
 6 import java.lang.reflect.Method;
 7 import java.lang.reflect.Proxy;
 8 
 9 //等我们会用这个类,自动生成代理类!  继承一个接口
10 public class ProxyInvocationHandler implements InvocationHandler {
11 
12     //被代理的接口
13     private Object target;
14 
15     public void setTarget(Object target) {
16         this.target = target;
17     }
18 
19     //生成得到代理类
20     public Object getProxy() {
21         return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
22     }
23 
24     @Override
25     //处理代理实例,并返回结果
26     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
27         //动态代理的本质就是使用反射机制实现
28         log(method.getName());//method.getName()得到方法的名字
29         Object result = method.invoke(target, args);
30         return result;
31     }
32 
33     public void log(String msg) {
34         System.out.println("执行了" + msg + "方法");
35     }
36 }

Client

 1 package com.xing.demo04;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         //真实角色
 6         UserServiceImpl userService = new UserServiceImpl();
 7         //代理角色
 8         ProxyInvocationHandler pih = new ProxyInvocationHandler();
 9 
10         pih.setTarget(userService);//设置要代理的对象
11 
12         //动态生成代理类
13         UserService proxy = (UserService) pih.getProxy();
14 
15         proxy.add();
16         proxy.delete();
17     }
18 }

 

如果实现别的实现类,只需修改Client中的真实角色就可

posted @ 2022-06-06 17:33  暴躁C语言  阅读(96)  评论(0编辑  收藏  举报