DAY -03 spring loc - id 和spring MVC

1. Spring的依赖注入



1.1 依赖注入案例



1.1.1 定义接口Pet

package com.jt.demo4;

public interface Pet {

    void hello();
}

1.1.2 定义Dog类

package com.jt.demo4;
import org.springframework.stereotype.Component;
//将该类交给Spring容器管理  key:abc,value:反射机制创建对象
@Component
public class Dog implements Pet{

    @Override
    public void hello() {
        System.out.println("快到圣诞节了!!!");
    }
}

1.1.3 定义User类

package com.jt.demo4;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component  //将User对象交给Spring容器管理
public class User {
    /**
     *  注入:将spring容器中的对象进行引用!!!
     *  @Autowired: 可以将容器中对象进行注入
     *      1.按照类型注入
     *          如果注入的类型是接口,则自动的查找其实现类对象进行注入
     *          注意事项: 一般spring框架内部的接口都是单实现,特殊条件下可以多实现
     *      2.按照名称注入
     */
    @Autowired
    private Pet pet;

    public void hello(){
        pet.hello();
    }
}

1.1.4 编辑配置类

package com.jt.demo4;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.jt.demo4")
public class SpringConfig {

    
}

1.1.5 编辑测试代码

package com.jt.demo4;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringDI {
    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = context.getBean(User.class);
        user.hello();
    }
}

1.3 MVC 设计思想
1.3.1 传统代码结构
说明: 如果将所有的业务代码都写到一个方法中,则导致后期维护耦合性高,为了提高程序的扩展性.将程序按照MVC设计思想 进行管理.

1.3.2 MVC设计思想说明
M: Model 数据层
V: View 视图层
C: Control 控制层
总结: MVC 主要的目的降低代码的耦合性,提高扩展性.方便后续开发.

在这里插入图片描述

1.3.3 "三层"代码结构
说明: 基于MVC设计思想的启发,在后端为了提高代码的扩展性,一般将后端代码分为三层.
分层:
1. Controller层 主要与页面进行交互 @Controller
2. Service层 主要实现后端的业务逻辑 @Service
3. Dao层/Mapper层 主要与数据库进行交互 也把该层称之为 “持久层” @Repository/@Mapper

1.4 "三层"代码结构实现
1.4.1 代码结构说明
包名: mapper 类2个 一个接口UserMapper/一个实现类 UserMapperImpl
包名: service 类2个 一个接口UserService/ 一个实现类UserServiceImpl
包名: controller 一个类: UserController
知识说明: 被调用的一般会有接口和实现类
1.4.2 编辑Mapper
1.编辑UserMapper

public interface UserMapper {

    void addUser();
}
  1. 编辑Mapper 实现类
@Repository //标识持久层 该类交给Spring容器管理 key:userMapperImpl value:对象
public class UserMapperImpl  implements UserMapper{

    @Override
    public void addUser() {
        System.out.println("新增用户成功!!!!");
    }
}

1.4.3 编辑Service

  1. 编辑UserService
public interface UserService {
    void addUser();
}
  1. 编辑UserServiceImpl
    package com.jt.demo5.service;
    
    import com.jt.demo5.mapper.UserMapper;
    import com.jt.demo5.mapper.UserMapperImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserServiceImpl implements UserService{
    
        @Autowired
        private UserMapper userMapper; //IOC+DI 解耦!!!!!
    
        @Override
        public void addUser() {
    
            userMapper.addUser();
        }
    }
    
    

    编辑Controller

  2. package com.jt.demo5.controller;
    
    import com.jt.demo5.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    @Controller //key=userController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        public void addUser(){
            userService.addUser();
        }
    }
    
    

    1.4.5 编辑配置类

  3. @Configuration
    @ComponentScan("com.jt.demo5")
    public class SpringConfig {
    
    }
    

    1.4.6 编辑测试类

  4. package com.jt.demo5;
    
    import com.jt.demo5.config.SpringConfig;
    import com.jt.demo5.controller.UserController;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class Spring_MVC {
    
        public static void main(String[] args) {
            ApplicationContext context =
                    new AnnotationConfigApplicationContext(SpringConfig.class);
            UserController userController = context.getBean(UserController.class);
            userController.addUser();
        }
    }
    
    

    1.5 @Value注解



    1.5.1 编辑properties文件

    # 1.数据结构:  key=value
    # 2.无需添加多余的引号
    # 3.注意多余的空格
    # 4.程序读取properties文件时,默认采用ISO-8859-1编码! 中文必定乱码
    name=张三
    

    1.5.2 编辑UserMapper

  5. public interface UserMapper {
    
        void addUser();
    }
    

    1.5.3 编辑UserMapperImpl

  6. package com.jt.demo6.mapper;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Repository;
    
    @Repository
    //spring根据指定的路径,加载properties配置文件 数据添加到spring容器中
    @PropertySource(value="classpath:/addUser.properties",encoding = "UTF-8")
    public class UserMapperImpl implements UserMapper{
        /**
         * @Value 注解的作用: 为属性赋值
         *        需求:  从spring容器中动态获取数据
         */
        @Value("${name}")
        //@Value("张三")  //直接写法,扩展性不好
        private String name;
    
        @Override
        public void addUser() {
            System.out.println("新增用户:" + name);
        }
    }
    

    1.5.4 编辑测试类

    package com.jt.demo6;
    
    import com.jt.demo6.config.SpringConfig;
    import com.jt.demo6.mapper.UserMapper;
    import com.jt.demo6.mapper.UserMapperImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class SpringValue {
    
        public static void main(String[] args) {
            ApplicationContext context =
                    new AnnotationConfigApplicationContext(SpringConfig.class);
            //获取的对象 实现类和接口都可以.
            UserMapper userMapper = context.getBean(UserMapper.class);
            userMapper.addUser();
        }
    }
    
    

    1.5.5 关于IOC-DI总结
    什么是IOC: 控制反转, 将对象交给Spring容器管理,由容器管理对象的生命周期.
    什么是DI: 依赖注入 为当前对象注入属性(属性也是对象).
    扩展问题: 如果采用配置文件xml的方式进行注入,则注入的方式有多种.
     1.set方式注入  
    1
     2.构造方法注入     
    1
     3.工厂模式注入.
    1
    总结: 使用IOC-DI可以极大程度上实现代码的松耦合(解耦)

    2. Spring-AOP

    2.2 AOP代码铺垫



    2.2.1 业务说明

    事务特性: 1. 原子性 2. 一致性 3.隔离性 4.持久性
    业务说明: 在增/删除/修改的操作过程中添加事务控制.

在这里插入图片描述

结论:
1. 如果按照上述的代码进行编辑,则所有增/删除/修改操作的代码都必须按照上述的规则.那么代码冗余.
2. UserService与事务控制代码紧紧的耦合在一起.不方便后期扩展. 以后尽可能保证业务的纯粹性.

2.2.2 关于代理模式说明
说明: 在业务层不方便做,但是又不得不做的事情,可以放到代理对象中. 通过这样的设计就可以解决业务层耦合的问题. 代理对象看起来和真是的对象 一模一样.所以用户使用不会察觉.

 类比:
1. 外卖也是一种典型的代理思想
2. 游戏代练
3. 房屋中介

 2.2.3 动态代理-JDK动态代理

package com.jt.demo1.proxy;

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

public class JDKProxy {
    /**
     * 获取代理对象
     * 参数说明:
     *  1. ClassLoader loader 类加载器 读取真实的类数据
     *  2. Class<?>[] interfaces, 要求传递接口信息
     *  3. InvocationHandler h  当代理对象执行方法时 执行
     * 注意事项: JDK代理必须要求 "被代理者"要么有接口(本身就是接口),要么实现接口(实现类).
     */

    public static Object getProxy(Object target){
        //1.获取类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2.获取接口
        Class[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(classLoader,interfaces,getInvocationHandler(target));
    }

    //代理对象执行方法时调用
    public static InvocationHandler getInvocationHandler(Object target){
        //这些代码都是写死的!!!!!!
        return new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("事务开始");
                //执行真实的业务方法
                Object result = method.invoke(target,args);
                System.out.println("事务提交");
                return result;
            }
        };
    }
}

2.2.4 业务代码测试

package com.jt.demo1;

import com.jt.demo1.config.SpringConfig;
import com.jt.demo1.proxy.JDKProxy;
import com.jt.demo1.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTx {

    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean(UserService.class);
        System.out.println(userService.getClass());
        //获取代理对象
        UserService proxy = (UserService) JDKProxy.getProxy(userService);
        System.out.println(proxy.getClass());
        //基于代理对象,执行业务操作 实现方法扩展
        proxy.addUser();
        proxy.deleteUser();
    }
}

在这里插入图片描述

 @Configuration 标识当前类是配置类
@ComponentScan 包扫描注解 扫描注解
@Bean 标识该方法的返回值交给Spring容器管理
@Scope 控制多例和单例
@Lazy 懒加载
@PostConstruct 初始化方法
@PreDestroy 销毁方法
@Component 将当前类未来的对象交给容器管理,在注解后面加括号("abc")那么这个spring将储存的id将变成abc
@Autowired 按照类型进行注入  有两种注入方式1.类型注入:如果注入的是接口则找到接口的实现类进行注入(注入的意思是spring容器里对象的引用)一般spring框架内部的接口都是但实现特殊情况也有多实现

@Qualifier 按照名称进行注入
@Repository 标识持久层注解
@Service 标识Service层
@Controller 标识Controller层
@Value 为属性赋值 @Value("${key}")
@PropertySource 加载指定路径的配置文件properties
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值