• spring


    一、spring IOC

    1.spring IOC定义

            IOC 是 Inversion of Control 的缩写,多数书籍翻译成“控制反转”。简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从⽽降低了解决问题的复杂度,⽽且可以灵活地被᯿⽤和扩展。IOC 理论提出的观点⼤体是这样的:借助于“第三⽅”实现具有依赖关系的对象之间的解耦。如下图:

    由于引进了中间位置的“第三⽅”,也就是 IOC 容器,使得 A、B、C、D 这 4 个对象没有了耦合关系,⻮轮之间的传动全部依靠“第三⽅”了,全部对象的控制权全部上缴给“第三⽅”IOC 容器,所以,IOC 容器成了整个系统的关键核⼼,它起到了⼀种类似“粘合剂”的作⽤,把系统中的所有对象粘合在⼀起发ഀ作⽤,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有⼈把 IOC 容器⽐喻成“粘合剂”的由来。  

            把上图中间的 IOC 容器拿掉,然后再来看看这套系统:

     

    现在看到的画⾯,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D 这 4 个对象之间已经没有了耦合关系,彼此毫⽆联系,这样的话,当你在实现 A 的时候,根本⽆须再去考虑 B、C 和 D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现 IOC 容器,对于系统开发⽽⾔,这将是⼀件多么美好的事情,参与开发的每⼀成员只要实现⾃⼰的类就可以了,跟别⼈没有任何关系!我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对⽐⼀下:

            软件系统在没有引⼊ IOC 容器之前,对象 A 依赖于对象 B,那么对象 A 在初始化或者运⾏到某⼀点的时候,⾃⼰必须主动去创建对象 B 或者使⽤已经创建的对象 B。⽆论是创建还是使⽤对象 B,控制权都在⾃⼰⼿上。软件系统在引⼊ IOC 容器之后,这种情形就完全改变了,由于 IOC 容器的加⼊,对象 A 与对象 B 之间失去了直接联系,所以,当对象 A 运⾏到需要对象 B 的时候,IOC 容器会主动创建⼀个对象 B 注⼊到对象 A 需要的地⽅。通过前后的对⽐,我们不难看出来:对象 A 获得依赖对象 B 的过程,由主动⾏为变为了被动⾏为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

    spring IOC 容器

    一、节省内存 十万个用户在注册:

            new User(name, age, height, sex){........} ​

            工具类对象:

            new xxxObj() ​ 如果IOC容器中有这个 唯一的对象 xxxObj

            机器性能更好

    2、松耦合: 面向抽象

    Student 对象需要 vehicle对象

    交通工具 Vehicle

    car

    bus

    plane

    bike

    3、bean容器的创建

    3.1.导包

    3.1.1.导入spring核心依赖包

    aop:jdk 语法、代理类

    1.

     

    2.

     

    编写application-context.xml文件

    1. "1.0" encoding="utf-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans
    5. https://www.springframework.org/schema/beans/spring-beans.xsd">
    6. <bean id="s" class="com.hqyj.model.Student">
    7. bean>
    8. beans>

    3.1.2编写语句

      1. package com.hqyj;
      2. import com.hqyj.model.Student;
      3. import org.springframework.beans.factory.BeanFactory;
      4. import org.springframework.context.ApplicationContext;
      5. import org.springframework.context.support.AbstractApplicationContext;
      6. import org.springframework.context.support.ClassPathXmlApplicationContext;
      7. import org.springframework.context.support.FileSystemXmlApplicationContext;
      8. public class MyTest1 {
      9.   public static void main(String[] args) {
      10.       //应用程序上下文,创建容器
      11.       //BeanFactory,ApplicationContext,AbstractApplicationContext是接口,不能new
      12.       //方法一:
      13. //       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
      14.       //方法二:
      15.       BeanFactory context = new ClassPathXmlApplicationContext("application-context.xml");
      16.        
      17.       //方法三:
      18. //       ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
      19.       //方法四:
      20. //       AbstractApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
      21.       //写法一:返回值Object
      22. //       Student student = (Student) context.getBean("s");
      23.       //写法二:获取类
      24.       Student student = context.getBean(Student.class);
      25.       student.work();
      26.   }
      27. }

    1. 测试

    3.2.容器bean对象创建的方式

    1、直接调 bean类 的构造方法
    2、调用静态工厂的静态方法创建bean对象
    3、调用实例工厂的   方法创建bean对象

    主要表现为:

    3.2.1 方法一

    1. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    2. BeanFactory context = new ClassPathXmlApplicationContext("application-context.xml");
    3. BeanFactory context = new FileSystemXmlApplicationContext("D:/hqyj/ssm/spring/studyIOC/src/application-context.xml");
    4. ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    5. AbstractApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    6. Resource rs=new FileSystemResource("D:\\Java\\chentaoWorkspace\\studySping-IOC\\src\\application-context.xml");
    7. BeanFactory beanFactory=new XmlBeanFactory(rs);
    8. beanFactory.getBean("student");
    9. BeanFactory context = new XmlBeanFactory(new FileSystemResource("D:/hqyj/ssm/spring/studyIOC/src/application-context.xml"));

    获取类写法:

    1.  //写法一:返回值Object
    2.        Student student1 = (Student) context.getBean("s");
    3.        Student student2 = (Student) context.getBean("s");
    4.        Student student3 = (Student) context.getBean("s");
    5. //写法二:获取类
    6. //      Student student1 = context.getBean(Student.class);
    7. //      Student student2 = context.getBean(Student.class);
    8. //      Student student3 = context.getBean(Student.class);

    3.2.2 方法二

     

    3.2.3 方法三

    调用实例工厂,创建bean对象

    1.    <bean id="maker" class="com.hqyj.model.StudentMaker" >bean>
    2.    <bean name="ms" factory-bean="maker" factory-method="make">bean>
    3.    <bean id="maker" class="com.hqyj.model.StudentMaker">bean>
    4.    <bean name="ms" factory-bean="maker" factory-method="make">bean>

    3.3.bean会创建多少个对象

    3.3.1.singleton—1个 单例

    创建一个对象

    <bean id="s" scope="singleton" class="com.hqyj.model.Student">

    3.3.2.prototype—多个 原型

    创建多个对象

     <bean id="s" scope="prototype" class="com.hqyj.model.Student">

    3.3.3.测试

    1. public static void main(String[] args) {
    2.        //应用程序上下文,创建容器
    3.        //BeanFactory,ApplicationContext,AbstractApplicationContext是接口,不能new
    4.        BeanFactory context = new ClassPathXmlApplicationContext("application-context.xml");
    5.        //返回值Object
    6.        Student student1 = (Student) context.getBean("s");
    7.        Student student2 = (Student) context.getBean("s");
    8.        Student student3 = (Student) context.getBean("s");
    9.        System.out.println(student1);
    10.        System.out.println(student2);
    11.        System.out.println(student3);
    12.        student1.work();
    13.   }

    3.4.bean 对象何时被创建

    3.4.1.容器创建时创建

    容器创建时就创建了,改为容器创建时不创建。设置为懒加载方式:

    lazy-init="true"

     

    3.4.2.获取的时候创建

    在getBean()时创建,必然是懒加载的

     

    3.5.bean对象的初始化和销毁

     

    二、IOC-DI依赖注入—给属性设置值

    DI: dependency Injection

    1、 DI依赖注入—xml文件注入方式

    1.1.简单数据注入

    1.1.1 使用set方法进行注入,spting自己调用

     

    1.1.2直接调用bean类的构造方法

    1. <bean name="s"
    2.     class="com.hqyj.model.Student">
    3. bean>

    第三方可能提供一个student.class 文件

    1. class StudentFactory{
    2. Student produce(){
    3. return new Studen t();
    4. }
    5. }

    1.1.3 引用别的bean对象

     

     

     

    1.1.4.名称空间注入

    namespace(XML文件)不常用

    1. <bean name="c1" class="com.hqyj.model.Car" p:brand="奔驰" p:color="黑色">
    2.      
    3. bean>

     

    1.2.复杂数据注入

    1.2.1.引入其他的bean的值

    使用ref关键字——ref = "其他bean的name"

    1.2.2 注入数组

    1. <bean name="c1" class="com.hqyj.model.Car" >
    2.        <property name="brand" value="宝马">property>
    3.        <property name="color" value="红色">property>
    4. bean>
    5. <bean name="s" class="com.hqyj.model.Student">
    6.        <property name="id" value="1">property>
    7.        <property name="name" value="zs">property>
    8.        <property name="age" value="10">property>
    9.        <property name="car" ref="c1">property>
    10.        <property name="objs">
    11.            <array>
    12.                <value>香蕉value>
    13.                <value>西瓜value>
    14.                <value>葡萄value>
    15.                <value>草莓value>
    16.                <ref bean="c1">ref>
    17.            array>
    18.        property>
    19. bean>

     

     

     

    以上的方法不建议使用

     

    通常要使用Arraay.tostring()方法对元素进行转化,转化后就显示的是具体的值。

    1.2.3 注入集合—list

    tostring()方法中不需要使用Array.tostring()方法,可以打印其元素:

     

    1. <bean name="c1" class="com.hqyj.model.Car" >
    2.       <property name="brand" value="宝马">property>
    3.       <property name="color" value="红色">property>
    4. bean>
    5. <bean name="s" class="com.hqyj.model.Student">
    6.       <property name="id" value="1">property>
    7.       <property name="name" value="zs">property>
    8.       <property name="age" value="10">property>
    9.       <property name="car" ref="c1">property>
    10.       <property name="objs">
    11.           <array>
    12.               <value>香蕉value>
    13.               <value>西瓜value>
    14.               <value>葡萄value>
    15.               <value>草莓value>
    16.               <ref bean="c1">ref>
    17.           array>
    18.       property>
    19.       <property name="likes">
    20.           <list>
    21.               <value>音乐value>
    22.               <value>跑步value>
    23.               <value>足球value>
    24.               <value>跳舞value>
    25.           list>
    26.       property>
    27. bean>
    28.  

     

     1.2.4.注入集合—set集合

     

     

     

    1.2.5.注入集合—map映射

    格式:

    
     
         
     
    

     

     

     

    1.2.6.注入集合—Properties

    会自动排序,与map相似

     

     

     

    1.3. DI依赖注入——xm文件方式的代码

    1. application-context.xml:
    2. <bean name="c1" class="com.hqyj.model.Car" >
    3.        <property name="brand" value="宝马">property>
    4.        <property name="color" value="红色">property>
    5. bean>
    6. <bean name="s" class="com.hqyj.model.Student">
    7.        <property name="id" value="1">property>
    8.        <property name="name" value="zs">property>
    9.        <property name="age" value="10">property>
    10.        <property name="car" ref="c1">property>
    11.        <property name="objs">
    12.            <array>
    13.                <value>香蕉value>
    14.                <value>西瓜value>
    15.                <value>葡萄value>
    16.                <value>草莓value>
    17.                <ref bean="c1">ref>
    18.            array>
    19.        property>
    20.        <property name="likes">
    21.            <list>
    22.                <value>音乐value>
    23.                <value>跑步value>
    24.                <value>足球value>
    25.                <value>跳舞value>
    26.            list>
    27.        property>
    28.        <property name="anm">
    29.            <set>
    30.                <value>value>
    31.                <value>value>
    32.                <value>青蛙value>
    33.                <value>乌龟value>
    34.            set>
    35.        property>
    36.        <property name="socres">
    37.            <map>
    38.                <entry key="数学" value="90">entry>
    39.                <entry key="英语" value="80">entry>
    40.                <entry key="体育" value="100">entry>
    41.                <entry key="美术" value="80">entry>
    42.            map>
    43.        property>
    44.        <property name="health">
    45.            <props>
    46.                <prop key="height">170厘米prop>
    47.                <prop key="weight">40千克prop>
    48.                <prop key="视力">5.2prop>
    49.                <prop key="血压">正常prop>
    50.            props>
    51.       property>
    52.  bean>
    实体类:Student:
    
    1. import java.util.*;
    2. public class Student {
    3.    private int id;
    4.    private String name;
    5.    private int age;
    6.    private Car car;
    7.    private Object[] objs;  //数组
    8.    private List likes;
    9.    private Set anm;
    10.    private Map socres;
    11.    private Properties health;
    12.    public Student(int id, String name, int age) {
    13.        System.out.println("id,name,age被调用了");
    14.        this.id = id;
    15.        this.name = name;
    16.        this.age = age;
    17.   }
    18.    public Student(String name,int id,  int age) {
    19.        System.out.println("name,id,age被调用了");
    20.        this.id = id;
    21.        this.name = name;
    22.        this.age = age;
    23.   }
    24.    public Properties getHealth() {
    25.        return health;
    26.   }
    27.    public void setHealth(Properties health) {
    28.        this.health = health;
    29.   }
    30.    public Map getSocres() {
    31.        return socres;
    32.   }
    33.    public void setSocres(Map socres) {
    34.        this.socres = socres;
    35.   }
    36.    public Set getAnm() {
    37.        return anm;
    38.   }
    39.    public void setAnm(Set anm) {
    40.        this.anm = anm;
    41.   }
    42.    public List getLikes() {
    43.        return likes;
    44.   }
    45.    public void setLikes(List likes) {
    46.        this.likes = likes;
    47.   }
    48.    public Object[] getObjs() {
    49.        return objs;
    50.   }
    51.    public void setObjs(Object[] objs) {
    52.        this.objs = objs;
    53.   }
    54.    public int getId() {
    55.        return id;
    56.   }
    57.    public void setId(int id) {
    58.        this.id = id;
    59.   }
    60.    public String getName() {
    61.        return name;
    62.   }
    63.    public void setName(String name) {
    64.        this.name = name;
    65.   }
    66.    public int getAge() {
    67.        return age;
    68.   }
    69.    public void setAge(int age) {
    70.        this.age = age;
    71.   }
    72.    public Car getCar() {
    73.        return car;
    74.   }
    75.    public void setCar(Car car) {
    76.        this.car = car;
    77.   }
    78.    @Override
    79.    public String toString() {
    80.        return "Student{" +
    81.                "id=" + id +
    82.                ", name='" + name + '\'' +
    83.                ", age=" + age +
    84.                ", car=" + car +
    85.                ", objs=" + Arrays.toString(objs) +
    86.                ", likes=" + likes +
    87.                ", anm=" + anm +
    88.                ", socres=" + socres +
    89.                ", health=" + health +
    90.                '}';
    91.   }
    92.    public Student() {
    93.        System.out.println("构造方法被调用");
    94.   }
    95.    public void work(){
    96.        System.out.println("干活");
    97.   }
    98.    public void xxx(){
    99.        System.out.println("初始化");
    100.   }
    101.    public void  yyy(){
    102.        System.out.println("销毁");
    103.   }
    104. }
    测试类:MyTest1:
    ​
    
    
    1. import com.hqyj.model.Car;
    2. import com.hqyj.model.Student;
    3. import org.springframework.beans.factory.BeanFactory;
    4. import org.springframework.beans.factory.xml.XmlBeanFactory;
    5. import org.springframework.context.ApplicationContext;
    6. import org.springframework.context.support.AbstractApplicationContext;
    7. import org.springframework.context.support.ClassPathXmlApplicationContext;
    8. import org.springframework.context.support.FileSystemXmlApplicationContext;
    9. import org.springframework.core.io.FileSystemResource;
    10. import org.springframework.core.io.Resource;
    11. public class MyTest1 {
    12.    public static void main(String[] args) {
    13.        //应用程序上下文,创建容器
    14.        //BeanFactory,ApplicationContext,AbstractApplicationContext是接口,不能new
    15.        AbstractApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    16. context.getBean(Student.class);
    17.        Student s = (Student) context.getBean("s");
    18.        System.out.println(s);
    19.   }
    20. }

    2、DI依赖注入—注解注入方式

    2.1.@Component注解—修饰了一个类

    2.1.1 组件

    @Component:组件,以下属于其组件

    @Controller 控制器

    @Service 服务层

    @Repository 持久层

    以上三者都继承于@Component

    1. @Component(value = "s")
    2. @Controller(value = "s")    
    3. @Service(value = "s")
    4. @Repository(value = "s")

    这就相当于在xml文件里面定义了一个组件

    容器创建,查看其创建了没?

    1. @Component
    2. public class Student {
    3.    private int id;
    4.    private String name;
    5.    private int age;
    6.    public Student() {
    7.        System.out.println("无参构造方法执行");
    8.   }
    9. }
    1. "1.0" encoding="utf-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.       xmlns:context="http://www.springframework.org/schema/context"
    5.       xsi:schemaLocation="
    6.        http://www.springframework.org/schema/beans
    7.        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    8.        http://www.springframework.org/schema/context
    9.        http://www.springframework.org/schema/context/spring-context.xsd">
    10.    
    11.    <context:annotation-config/>
    12.    <context:component-scan base-package="com.hqyj.model">context:component-scan>
    13. beans>
     
    

    2.1.2 给属性赋值

    1. package com.hqyj.model;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.stereotype.Component;
    4. @Component(value = "s")
    5. public class Student {
    6.    @Value("1")
    7.    private int id;
    8.    @Value("zs")
    9.    private String name = "i";
    10.    @Value("10")
    11.    private int age;
    12.    public Student() {
    13.        System.out.println("无参构造方法执行");
    14.   }
    15.    public String getName() {
    16.        return name;
    17.   }
    18.    @Override
    19.    public String toString() {
    20.        return "Student{" +
    21.                "id=" + id +
    22.                ", name='" + name + '\'' +
    23.                ", age=" + age +
    24.                '}';
    25.   }
    26. }
    1. public class MyTest1 {
    2.    public static void main(String[] args) {
    3.        //应用程序上下文,创建容器
    4.        //BeanFactory,ApplicationContext,AbstractApplicationContext是接口,不能new
    5.        AbstractApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    6.        //注解注入DI
    7.        Student s = (Student) context.getBean("s");
    8.       System.out.println(s);
    9.   }
    10. }

    2.2.@Value注解—设置属性

    1. package com.hqyj.model;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.stereotype.Component;
    4. @Component()
    5. public class Student {
    6.    @Value("1")
    7.    private int id;
    8.    @Value("zs")
    9.    private String name = "i";
    10.    @Value("10")
    11.    private int age;
    12.    public Student() {
    13.        System.out.println("无参构造方法执行");
    14.   }
    15.    public String getName() {
    16.        return name;
    17.   }
    18.    @Override
    19.    public String toString() {
    20.        return "Student{" +
    21.                "id=" + id +
    22.                ", name='" + name + '\'' +
    23.                ", age=" + age +
    24.                '}';
    25.   }
    26. }
    1. //注解注入DI
    2. Student s = context.getBean(Student.class);
    3. System.out.println(s);   //zs

     

    2.3.@Resource注解—获得对象

    不是spring框架下的注解,包不同,是属于其他的特有功能的注解

    2.3.1 根据类型注入

     

     

    1. package com.hqyj.model;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.stereotype.Component;
    4. import javax.annotation.Resource;
    5. import javax.annotation.Resources;
    6. @Component(value = "s")
    7. public class Student {
    8.    @Value("1")
    9.    private int id;
    10.    @Value("zs")
    11.    private String name = "i";
    12.    @Value("10")
    13.    private int age;
    14.    @Resource()
    15.    private Car car;
    16.    public Student() {
    17.        System.out.println("无参构造方法执行");
    18.   }
    19. }

    2.3.2 name指定资源

    注意:一一对应

     

    2.4.Autowired—自动注入,根据类型

     

    当容器中有两个一样的对象时,拿到哪一个对象呢?

    2.4.1 bean声明两个car

     

    报错,两个bean表示时,有冲突

    2.4.2.当注解有一个car对象,bean有一个car对象

    注解优先,起作用,不会报错

    2.4.3.解决问题—配合使用

    @Autowired@Qualifier(value = "c2")  配合使用

     
    
    1. @Qualifier(value = "c2")   //候选的合格者
    2.    @Qualifier("c2")   //候选的合格者
    3. 功能相同:

     

    2.5.java Configuration

    2.5.1 容器创建——放入容器

    创建容器的时候就直接加载这个类MyConfig.class

    @Configutation //相当于一个xml文件

    Class MyConfig{

    @Bean

    Student fun(){

    return new Student("","");

    }

    }

     

     

    2.5.2 从容器中取

     

    1. @Configuration
    2. public class MyConfig {
    3.    @Bean
    4.    Student fun(Car car){    //Car从容器中拿取
    5. //       Car car = new Car("梅赛德斯","蓝色");
    6.        return new Student(1,"小花",20,car);
    7.   }
    8.    @Bean      //放在容器中
    9.    Car car(){
    10.        return  new Car("奎蟒","蓝黑");
    11.   }
    12. }

    2.6、松耦合

    2.6.1 vehice对象

    Student 需要 vehice对象?

    交通工具vehicle:

    car

    bus

    plane

    bike

    interface vehicle(){

    go(); //抽象

    }

     

     

     

     

    三.(重点)IOC-DI依赖注入- 面试题

    IOC / DI: IOC不是一种技术,主要是一种设计思想。在项目中,传统创建方法是new一个对象,但这样会使得对象间的耦合度增加。 Spring将所有的对象都登机在Spring容器中,并且在系统运行适当的时候通过DI注入到对象当中。 控制反转就是将对象的注册从对象中创建 反转为 Spring统一注册。

    四、spring AOP

    改变对象原有的行为,但又无法改变源代码

    aop:面向切面编程:与过滤器filter相似

    1、Aop概念

    连接点Joinpoint可以进行切入开发的点。如一个方法、一个代码块、一个try块(AspectJ中原本规定可以有这些)。但是spring**只支持把方法作为连接点**。
    切入点Pointcut已经被选定作为切面开发的点。
    通知/增强Advice对切入点可以做的各种事情。如前置通知before()、后置通知after()、环绕通知around()、异常通知exception()等。 java程序中,往往把这些通知放入到一个额外的类中书写。
    目标对象Target(略) 目标对象是被切入的对象。但是由于类是对象的模板,是由类new()出来的,所以目标当然就是一个个的类了。
    代理对象Proxy(略)由于本章节,是spring自行内在完成代理对象的所有工作,我们只管用就好,所以不必专门学习。如果要知道原理请学习动态代理。
    切面Aspect切入点被融入通知后,产生的整体效应。(不必强行理解这个词)

    2、面向切面编程

    2.1. 定义——画图方式理解

    AsprctJ:定义了非常丰富的面向切面,各种切法

    spring:Interceptor 拦截器

    开门 person.openDoor()---自动--->door.open()

    进入 person.enter();

    关门 person.close()---自动----->door.close()

     

    2.2. 步骤

    2.2.1.导包

    *aspectj*下载的地方:

    AspectJ Downloads | The Eclipse Foundation

    aspectjweaver下载的地方:

    http://mvnrepository.com/artifact/org.aspectj/aspectjweaver/1.8.7

    我用的是其中这两个包

    aspectj-1.8.13.jar aspectjweaver-1.8.7.jar
    AspectJ的高版本可能一个包就可以了

    当然spring的aop包也得有,我用的是

    spring-aop-4.3.4.RELEASE.jar

    spring-aspects-4.3.4.RELEASE.jar

     

    2.2.2.编写代码

    1.Person.java

    1. package com.hqyj.model;
    2. public class Person {
    3.   public void enter(){
    4.       System.out.println("enter()方法被调用...");
    5.   }
    6. }

    2.DoorAdvice.java

    1. package com.hqyj.model;
    2. public class DoorAdvice {
    3.   void open(){
    4.       System.out.println("开门");
    5.   }
    6.   void close(){
    7.       System.out.println("关门");
    8.   }
    9. }

    3.Application-context.xml

    1. "1.0" encoding="utf-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.       xmlns:context="http://www.springframework.org/schema/context"
    5.       xmlns:aop="http://www.springframework.org/schema/aop"
    6.       xsi:schemaLocation="
    7.       http://www.springframework.org/schema/beans
    8.       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    9.       http://www.springframework.org/schema/aop
    10.     http://www.springframework.org/schema/aop/spring-aop.xsd
    11.       http://www.springframework.org/schema/context
    12.       http://www.springframework.org/schema/context/spring-context.xsd">
    13.   <bean class="com.hqyj.model.Person">bean>
    14.   <bean id="doorAdvice" class="com.hqyj.model.DoorAdvice">bean>
    15.   <aop:config>
    16.       <aop:pointcut id="enter" expression="execution(public void com.hqyj.model.Person.enter())"/>
    17.       <aop:aspect ref="doorAdvice">
    18.           <aop:before method="open" pointcut-ref="enter">aop:before>
    19.           <aop:after method="close" pointcut-ref="enter">aop:after>
    20.       aop:aspect>
    21.   aop:config>
    22. beans>

    4.MyTestDoor.java

    1. package com.hqyj;
    2. import com.hqyj.model.Person;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. public class MyTestDoor {
    5.   public static void main(String[] args) {
    6.       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    7.       Person person = context.getBean(Person.class);
    8.       person.enter();
    9.   }
    10. }

    结果

     

    2.2.3.对比结果

     

     

    3.面向切面编程的方式

    3.1.配置文件xml方式

    3.1.1 解释

    Before() 前置通知

    After() 后置通知

    After-returning() //后置通知,出现异常不调用

    After_throwing() /后置通知,发生了异常才执行,否则不执行

    Around() 环绕

    特殊功能:有过滤性质,会过滤掉目标方法

    3.1.2 代码

    1. package com.hqyj.model;
    2. import org.aspectj.lang.ProceedingJoinPoint;
    3. public class DoorAdvice {
    4.    void before(){  //前置通知
    5.        System.out.println("before()");
    6.   }
    7.    void after(){     //后置通知
    8.        System.out.println("after()");
    9.   }
    10.    void after_returning(){   //异常通知,出现异常不调用
    11.        System.out.println("after_returning()");
    12.   }
    13.    void after_throwing(){    //发生了异常才执行,否则不执行
    14.        System.out.println("发生了异常");
    15.   }
    16.    Object around(ProceedingJoinPoint point) throws Throwable {
    17.        System.out.println("环绕通知1");   //前置环绕
    18.        Object proceed = point.proceed();   //调用目标方法
    19.        System.out.println("环绕通知2");   //后置环绕
    20.        return proceed;   //返回去
    21.   }
    22. }
    1. <aop:config>
    2.        <aop:pointcut id="enter" expression="execution(public void com.hqyj.model.Person.enter())"/>
    3.        <aop:aspect ref="doorAdvice">
    4.            <aop:before method="before"  pointcut-ref="enter">aop:before>
    5.            <aop:after method="after" pointcut-ref="enter">aop:after>
    6.            <aop:after-returning method="after_returning" pointcut-ref="enter">aop:after-returning>
    7.            <aop:after-throwing method="after_throwing" pointcut-ref="enter">aop:after-throwing>
    8.            <aop:around method="around" pointcut-ref="enter" >aop:around>
    9.       aop:aspect>
    10. aop:config>

    3.2.使用注解的方式

    1. xml中 声明了通知类和被切入的person
    2. <aop:config>    
    3. 通知类 door
    4. 被切入的 person
    5. 注解:
    6.   @Aspect:放在通知类的上面  
    7.   Pointcut:切入点

    3.2.1.加入aop自动代理

    1.   <aop:aspectj-autoproxy/>

    3.2.2.代码

    1. DoorAdvice.java:
    2. package com.hqyj.model;
    3. import org.aspectj.lang.ProceedingJoinPoint;
    4. import org.aspectj.lang.annotation.*;
    5. @Aspect
    6. class DoorAdvice {
    7.    @Pointcut("execution(public void com.hqyj.model.Person.enter())")
    8.    void point(){   //代表切点,空方法
    9.   }
    10.    @Before("DoorAdvice.point()")
    11.    void before(){  //开始方法
    12.        System.out.println("before()");
    13.   }
    14.    @After("DoorAdvice.point()")
    15.    void after(){     //结束方法
    16.        System.out.println("after()");
    17.   }
    18.    @AfterReturning("DoorAdvice.point()")
    19.    void after_returning(){   //异常
    20.        System.out.println("after_returning()");
    21.   }
    22.    @AfterThrowing("DoorAdvice.point()")
    23.    void after_throwing(){    //发生了异常才执行,否则不执行
    24.        System.out.println("发生了异常");
    25.   }
    26.    @Around("DoorAdvice.point()")
    27.    Object around(ProceedingJoinPoint point) throws Throwable {
    28.        System.out.println("环绕通知1");   //前环绕
    29.        Object proceed = point.proceed();   //调用目标方法
    30.        System.out.println("环绕通知2");   //后环绕
    31.        return proceed;   //返回去
    32.   }
    33. }
    1. Person.java
    2. package com.hqyj.model;
    3. public class Person {
    4.    public void enter(){
    5.        System.out.println("enter()方法被调用...");
    6.   }
    7. }

    2.3.注解执行的顺序

     

    4、面试题

    友情提示:

    面向切面编程,面试要问哈,AOP是在OOP基础之上的一种更高级的设计思想。 java这个方向,IOC/DI/、AOP不问的话没有什么问的了,重要的框架都是基于这些思想设计的

    1.around和过滤器filter的区别

            只有@Around方法能够达到“拦截住而不放行”的效果。

            @Around会强制要求所修饰的方法含有参数(ProceedingJoinPoint point),因为这个参数就是用于控制是否放行的。

            point.proceed()代表放行,有点类似Servlet规范中的Filter的Chain.doFilter(req,resp)。下表来对比一下写法

    @Around@Around("TransactionAdvice.pointCut()")*public* Object around(ProceedingJoinPoint point) *throws* Throwable { System.*out***.println("环绕 前通知被执行"); Object proceed = point.proceed();//放行,实际是它可以调用目标方法 System.*out***.println("环绕 后通知被执行"); *return* proceed;}
    过滤器Filter*public* *class* AllFilter *implements* Filter{ @Override*public* *void* doFilter(ServletRequest request, ServletResponse response, FilterChain chain) *throws* IOException, ServletException { System.*out***.println("时间1=" + System.currentTimeMillis()); chain.doFilter(request, response); //放行 将请求传递下去 System.*out***.println("时间2=" + System.currentTimeMillis());}}

    五、事务

    一般指的是数据库操作

    也指的是不可分割的操作(要么都完成,要么都不完成)

    一条sql语句 是不是一个事务?

    是一个事务。单条sql相当于自动提交了。

    1.原生—事务步骤

    开启事务(关闭自动提交):

    connection.set()
    connection.begin.Transaction()
    conn.setAutoCommit(false);
    1. 操作1 sql1

    2. 操作2 sql2

    3. 操作3 sql3

    4. 操作4 sql4

    提交事务:submit()

    2.代码

    1. package com.hqyj;
    2. import java.sql.Connection;
    3. import java.sql.DriverManager;
    4. import java.sql.SQLException;
    5. import java.sql.Statement;
    6. public class MyTest1 {
    7.    private static final String DIRVER = "com.mysql.jdbc.Driver";
    8.    private static final String URL = "jdbc:mysql://localhost:3306/shop";
    9.    private static final String USER = "root";
    10.    private static final String PASSWORD = "123456";
    11.    public static void main(String[] args)  throws Exception{
    12.        Class.forName(DIRVER);
    13.        Connection conn = DriverManager.getConnection(URL,USER,PASSWORD);
    14.        conn.setAutoCommit(false);   //关闭自动提交
    15.        Statement stmt = conn.createStatement();
    16.        try {
    17.            int  num1= stmt.executeUpdate("update book set price = price-100 where id = 1");
    18.            System.out.println("num1=" + num1);
    19.            int  a = 5/0; //异常
    20.            int  num2= stmt.executeUpdate("update book set price = price+100 where id = 2");
    21.            System.out.println("num2=" + num2);
    22.            conn.commit();    //提交事务
    23.       } catch (Exception throwables) {
    24.            conn.rollback();   //事务发生异常,数据要回滚
    25.            throwables.printStackTrace();
    26.            System.out.println("发生了运行时异常");
    27.       } finally {
    28.            stmt.close();
    29.            conn.close();
    30.       }
    31.   }
    32. }

    3.代码繁琐,化简

    解决办法,切入事务,利用AOP

    需要用到c3p0数据源来用,需要写成一个bean。

    切入点:只支持方法

    3.1导包

     

    3.2代码

    1. package com.hqyj.Teansaction;
    2. import com.mchange.v2.c3p0.ComboPooledDataSource;
    3. import org.springframework.jdbc.core.JdbcTemplate;
    4. public class MyTest2 {
    5.    public static void main(String[] args) throws Exception {
    6.        ComboPooledDataSource dataSource = new ComboPooledDataSource();
    7.        dataSource.setDriverClass("com.mysql.jdbc.Driver");
    8.        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/shop");
    9.        dataSource.setUser("root");
    10.        dataSource.setPassword("123456");
    11.        //spring有一个轻量级的数据 访问框架jdbc Template
    12.        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    13.        int num1 = jdbcTemplate.update("Update book set price = price-100 where id=1");
    14.        int num2 = jdbcTemplate.update("Update book set price = price+100 where id=2");
    15.        System.out.println("num1="+num1);
    16.        System.out.println("num2="+num2);
    17.   }
    18. }

    4、切入事务,xml文件方式

    4.1新建一个bean对象—Account.java

    1. application-context.xml:
    2. <bean id="dataSource"  class="com.mchange.v2.c3p0.ComboPooledDataSource">
    3.            <property name="driverClass" value="com.mysql.jdbc.Driver">property>
    4.            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop?useSSL=false&Timezone=GMT">property>
    5.            <property name="user" value="root">property>
    6.            <property name="password" value="123456">property>
    7.        bean>
    8.        <bean class="org.springframework.jdbc.core.JdbcTemplate">
    9.            <property name="dataSource" ref="dataSource">property>
    10.        bean>
    11.    <context:component-scan base-package="com.hqyj.model">context:component-scan>
    Account类:
        
    
    1. package com.hqyj.model;
    2. import com.mchange.v2.c3p0.ComboPooledDataSource;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import org.springframework.stereotype.Component;
    6. import javax.sql.DataSource;
    7. @Component
    8. public class Account {
    9. @Autowired
    10.    DataSource dataSource;
    11. @Autowired
    12.    JdbcTemplate jdbcTemplate;
    13.    //转账
    14.    public void teansfer() throws Exception {
    15.        System.out.println(dataSource);
    16.        //spring有一个轻量级的数据 访问框架jdbc Template
    17.        int num1 = jdbcTemplate.update("Update book set price = price-100 where id=1");
    18.        int num2 = jdbcTemplate.update("Update book set price = price+100 where id=2");
    19.        System.out.println("num1="+num1);
    20.        System.out.println("num2="+num2);
    21.   }
    22. }
    测试类:
        
    
    1. package com.hqyj.Teansaction;
    2. import com.hqyj.model.Account;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. public class MyTest2 {
    5.    public static void main(String[] args) throws Exception {
    6.        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Application-context.xml");
    7.        Account account = context.getBean(Account.class);
    8.        account.teansfer();
    9.   }
    10. }

    4.2 通知配置

     

    4.3 事务的传递性

    read-only = "true"

    性能1:读
    性能2:写
    ​
    1.读 2.可以改
            1000  ,   1500          
    1.改 2.不能改
            1000  ,   500

    ​
    配置文件:
    ​
    
    1. "1.0" encoding="utf-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.       xmlns:context="http://www.springframework.org/schema/context"
    5.       xmlns:aop="http://www.springframework.org/schema/aop"
    6.       xmlns:tx="http://www.springframework.org/schema/tx"
    7.       xsi:schemaLocation="
    8.        http://www.springframework.org/schema/beans
    9.        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    10.        http://www.springframework.org/schema/aop
    11. http://www.springframework.org/schema/aop/spring-aop.xsd
    12. http://www.springframework.org/schema/tx
    13.        http://www.springframework.org/schema/tx/spring-tx.xsd
    14.        http://www.springframework.org/schema/context
    15.        http://www.springframework.org/schema/context/spring-context.xsd">
    16.        <tx:advice id="txAdvice" transaction-manager="transactionManager">
    17.            <tx:attributes>
    18.                <tx:method name="add**" propagation="REQUIRED" />
    19.                <tx:method name="delete**" propagation="REQUIRED" />
    20.                <tx:method name="transfer**" propagation="REQUIRED"/>
    21.                <tx:method name="select**" propagation="SUPPORTS" read-only="true"/>
    22.            tx:attributes>
    23.        tx:advice>
    24.        <aop:config>
    25.            <aop:pointcut id="serviceMethod" expression="execution(* com.hqyj.service..*.*(..))"/>
    26.            <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod">aop:advisor>
    27.        aop:config>
    28.        <bean  id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    29.            <property name="dataSource" ref="dataSource">property>
    30.        bean>
    31.        <bean id="dataSource"  class="com.mchange.v2.c3p0.ComboPooledDataSource">
    32.            <property name="driverClass" value="com.mysql.jdbc.Driver">property>
    33.            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop?useSSL=false&Timezone=GMT">property>
    34.            <property name="user" value="root">property>
    35.            <property name="password" value="123456">property>
    36.        bean>
    37.        <bean class="org.springframework.jdbc.core.JdbcTemplate">
    38.            <property name="dataSource" ref="dataSource">property>
    39.        bean>
    40.    <context:component-scan base-package="com.hqyj.service">context:component-scan>
    41. beans>
    AccountService.java
    ​
    
    
    1. package com.hqyj.service;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.beans.factory.annotation.Qualifier;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import org.springframework.stereotype.Component;
    6. import javax.sql.DataSource;
    7. @Component
    8. public class AccountService {
    9. @Autowired()
    10. @Qualifier("dataSource")
    11.    DataSource dataSource;
    12. @Autowired
    13.    JdbcTemplate jdbcTemplate;
    14.    //转账
    15.    public void teansfer() throws Exception {
    16.        System.out.println(dataSource);
    17.        //spring有一个轻量级的数据 访问框架jdbc Template
    18.        int num1 = jdbcTemplate.update("Update book set price = price-100 where id=1");
    19. //       int i = 5/0;
    20.        int num2 = jdbcTemplate.update("Update book set price = price+100 where id=2");
    21.        System.out.println("num1="+num1);
    22.        System.out.println("num2="+num2);
    23.   }
    24. }
    测试类:
    ​
    
    
    1. package com.hqyj.Teansaction;
    2. import com.hqyj.service.AccountService;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. public class MyTest2 {
    5.    public static void main(String[] args) throws Exception {
    6.        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Application-context.xml");
    7.        AccountService account = context.getBean(AccountService.class);
    8.        account.teansfer();
    9.   }
    10. }

     

    #####

    5.切入,注解方式

     

    @Transactional标在方法上,如果每一个方法都是一样的直接标在类上
    
    1. package com.hqyj.service;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.beans.factory.annotation.Qualifier;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import org.springframework.stereotype.Component;
    6. import org.springframework.transaction.annotation.Propagation;
    7. import org.springframework.transaction.annotation.Transactional;
    8. import javax.sql.DataSource;
    9. @Component
    10. public class AccountService {
    11. @Autowired()
    12.    DataSource dataSource;
    13. @Autowired
    14.    JdbcTemplate jdbcTemplate;
    15.    //转账
    16.    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    17.    public void teansfer() throws Exception {
    18.        System.out.println(dataSource);
    19.        //spring有一个轻量级的数据 访问框架jdbc Template
    20.        int num1 = jdbcTemplate.update("Update book set price = price-100 where id=1");
    21.        int i = 5/0;
    22.        int num2 = jdbcTemplate.update("Update book set price = price+100 where id=2");
    23.        System.out.println("num1="+num1);
    24.        System.out.println("num2="+num2);
    25.   }
    26. }

    web开发:servlet + jsp (html,css,js) ajax

    六、建立web项目

    1.MVC

    1.1.MVC思想

    C : controller 控制器 接收用户的请求(Tomcat)

    M: model 多个模型 数据库

    V : view 视图 用户看到的内容(jsp)

    @Reposiary

    @controller

    @service

    @Repository


    1.2.java项目结构

    1.2.1一般的Java项目:idea支持多模块的

    src: 源代码

    out: (bin) 编译后的字节码文件

    1.2.2web项目

    web项目要放到tomcat中执行

    maven:

    src: 源代码

    web: 里面的东西会发布到tomcat中

    WEB-INF

    class: 编译后的字节码文件

    lib: jar包(spring...)

    web.xml: 描述了整个项目

    METE-INF

    任意文件: jsp文件、HTML文件、css文件、js文件

    2、建立web项目

    2.1.idea建web项目

    创建web项目

     

    部署tomcat服务器

     

     

     

     

    解释:

    Deployment:部署

    war:添加需要运行的项目,war包----->war exploded

    Artifacts:

    一个目录

    一个jar包

    一个war包

    apk文件

    Application context : 访问项目的路径 http://localhost:8080/项目名/index.jsp

    部署到tomcat上,以什么名字访问

    2.2.idea建maven项目

    3.控制器类

    3.1.接口分析

    Servlet1 /abc

    Servlet2 z

    Servlet3 /mn

    Servlet4

    ServletN

    安全性??? 单入口

        单个Servlet
    ​
                    case  '/aaa'
                    调用      功能1
    ​
                    case  'b'
                    调用      功能2
    ​
                    case  '/ccc'
                    调用·     功能3
    ​
                    case  '/ddd'
                    调用      功能4
    ​
                    case  'e'
                    调用      功能5

    3.2.控制器——url路径

    url-------方法

    发送过来的请求都被DispatcherServlet接收了,DispatcherServlet可以去查找控制器,需要去指定对应的文件

    1. @Controller
    2. public class BookController {
    3.    @RequestMapping("/abc")
    4.    String work(){
    5.        System.out.println("work----干活");
    6.        return "/index.jsp";
    7.   }
    8. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.       xmlns:context="http://www.springframework.org/schema/context"
    5.       xmlns:mvc="http://www.springframework.org/schema/mvc"
    6.       xmlns:aop="http://www.springframework.org/schema/aop"
    7.       xsi:schemaLocation="
    8.       http://www.springframework.org/schema/mvc
    9.   http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    10.   http://www.springframework.org/schema/beans
    11.   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    12.       http://www.springframework.org/schema/context
    13.       http://www.springframework.org/schema/context/spring-context-4.3.xsd
    14.   http://www.springframework.org/schema/aop
    15.   http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    16.    <context:component-scan base-package="com.hqyj.controller"/>
    17. beans>
    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5.         version="4.0">
    6.    <welcome-file-list>
    7.        <welcome-file>index.htmlwelcome-file>
    8.    welcome-file-list>
    9.    <servlet>
    10.        <servlet-name>DispatcherServletservlet-name>
    11.        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    12.        <init-param>
    13.            <param-name>contextConfigLocationparam-name>
    14.            <param-value>classpath:config/spring-mvc.xmlparam-value>
    15.        init-param>
    16.        <load-on-startup>1load-on-startup>
    17.    servlet>
    18.    <servlet-mapping>
    19.        <servlet-name>DispatcherServletservlet-name>
    20.        <url-pattern>/url-pattern>
    21.    servlet-mapping>
    22. web-app>

    使用注解时,如果不起作用

    1.    <mvc:annotation-driven/>

    3.3.静态资源

    3.3.1常见的静态资源

    图片

    html文件

    Css文件

    用来spring框架后静态资源直接访问时访问不了的,原因:

    DispatcheServlet接收所有的请求,/,都走RequestMapping

    所以走RequestMapping指定的文件才能访问,唯一特殊的时index.jsp文件,因为时单入口y.

    3.3.2 静态资源访问解决方式

    法一:

    使用给mvc:resource,对静态资源进行配置,不被deispatcher按默认方式处理。可以直接访问

    1. <mvc:resources mapping="/css/**" location="/css/"/>
    2. <mvc:resources mapping="/js/**" location="/js/"/>
    3. <mvc:resources mapping="/img/**" location="/img/"/>
    4. <mvc:resources mapping="/html/**" location="/html/"/>
    5. <mvc:resources mapping="/**" location="/"/>
    6. <mvc:annotation-driven/>

    法二:

    静态资源同一放在static目录下

     
    
    1. <mvc:resources mapping="/static/**" location="/static/"/>
    2. <mvc:resources mapping="/**" location="/"/>
    3. <mvc:annotation-driven/>

     

     

    3.4.视图解析器

    3.4.1方式1 直接写

    因为直接访问视图文件会导致报错或者不完整,所有要隐藏视图文件

    将视图文件藏起来——藏在WEB-INF,黑客访问的话,就不会访问到。

     

    1. package com.hqyj.controller;
    2. import org.springframework.stereotype.Component;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.xml.ws.RequestWrapper;
    7. @Controller
    8. public class BookController {
    9.    @RequestMapping("/abc")
    10.    String work(HttpServletRequest request){
    11.        System.out.println("work----干活");
    12.        String name = "安其拉";
    13.        request.setAttribute("name",name);
    14.        return "/WEB-INF/abc.jsp";    //那视图文件
    15.   }
    16. }

    3.4.2 简化管理

    然后为了方便管理,在WEB-INF下建立一个jsp文件夹,里面再建立一个用来表示时哪一个项目的文件,此项目是Book的。book里面存放jsp文件,记得要改动return的路径哟

     

     

    3.4.3 设置视图解析器

    return "/WEB-INF/jsp/book/abc.jsp"; 
    太复杂,有公共的部分,所以运用视图解析器更方便

    设置视图解析器前缀和后缀

    1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    2.    <property name="prefix" value="/WEB-INF/jsp/">property>
    3.    <property name="suffix" value=".jsp">property>
    4. bean>

     

     

     

    3.5.缓解控制冲突

    因为如果路径就设置为/add的话,有很多个添加操作,就会冲突,所以需要在控制器上使用RequestMapping("/book")

     

     

    1. @Controller
    2. @RequestMapping("/book")
    3. public class BookController {
    4.    @RequestMapping("/work")
    5.    String work(HttpServletRequest request){
    6.        System.out.println("work----干活");
    7.        String name = "安其拉";
    8.        request.setAttribute("name",name);
    9.        return "book/abc";    //那视图文件
    10.   }
    11.    @RequestMapping("/add")
    12.    String add(){
    13.        return "book/add";
    14.   }
    15. }

    3.6.设置addAttribute属性

    3.6.1 request.setAttribute

     

    3.6.2 model.addAttribute

     

    3.6.3当两个都存在时,model起作用

     

     

    1. package com.hqyj.controller;
    2. import org.springframework.stereotype.Component;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.ui.Model;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.xml.ws.RequestWrapper;
    8. @Controller
    9. @RequestMapping("/book")
    10. public class BookController {
    11.    @RequestMapping("/work")
    12.    String work(HttpServletRequest request, Model model){
    13.        System.out.println("work----干活");
    14.        String name = "潘江";
    15.        model.addAttribute("name","tom");
    16.        request.setAttribute("name",name);
    17.        return "book/abc";    //那视图文件
    18.   }
    19.    @RequestMapping("/add")
    20.    String add(){
    21.        return "book/add";
    22.   }
    23. }

    3.7.控制器类

    3.7.1控制器类型

     

    3.7.2 控制器的返回值

    http 状态码

    200 运行成功,正常

    301,302,303 资源转移了,重定向

    404 资源不存在

    500 服务器运行出错

    405 资源不存在

    3.7.2.1.String

    返回的String类型 ,其中只要含有redirect,就是一个重定向

    重定向:分为相对定位和绝对定位,详看7.3重定向

    3.7.2.2.ModelAndersonView

    new ModelAndView(页面的地址,传递的数据名,传递的数据)

    1. @RequestMapping("sleep")
    2.    ModelAndView sleep(Model model){
    3.        
    4.        String nick = "张三";
    5.        return new ModelAndView("book/sleep","nick",nick);     //拿页面
    6.   }

     

    也可以传递对象Book

    1. @RequestMapping("/sleep")
    2. ModelAndView sleep(Model model){
    3.    Book book = new Book(1,"成都的街头","爱尔华斯",200);
    4.    return new ModelAndView("book/sleep","book",book);     //拿页面
    5. }
    1. package com.hqyj.model;
    2. public class Book {
    3.    private int id;
    4.    private String name;
    5.    private String author;
    6.    private double price;
    7.    public Book() {
    8.   }
    9.    public Book(int id, String name, String author, double price) {
    10.        this.id = id;
    11.        this.name = name;
    12.        this.author = author;
    13.        this.price = price;
    14.   }
    15.    public int getId() {
    16.        return id;
    17.   }
    18.    public void setId(int id) {
    19.        this.id = id;
    20.   }
    21.    public String getName() {
    22.        return name;
    23.   }
    24.    public void setName(String name) {
    25.        this.name = name;
    26.   }
    27.    public String getAuthor() {
    28.        return author;
    29.   }
    30.    public void setAuthor(String author) {
    31.        this.author = author;
    32.   }
    33.    public double getPrice() {
    34.        return price;
    35.   }
    36.    public void setPrice(double price) {
    37.        this.price = price;
    38.   }
    39.    @Override
    40.    public String toString() {
    41.        return "Book{" +
    42.                "id=" + id +
    43.                ", name='" + name + '\'' +
    44.                ", author='" + author + '\'' +
    45.                ", price=" + price +
    46.                '}';
    47.   }
    48. }
    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4.    <title>Titletitle>
    5. head>
    6. <body>
    7.   sleep----ModelAndView  <br>
    8.   ${book.id}
    9.   ${book.name}
    10.   ${book.author}
    11.   ${book.price}
    12. body>
    13. html>

     

    3.7.2.3.Object对象

    Object对象默认拿取jsp界面

    object对象添加@ResponseBody表示不拿jsp页面,纯数据,可以用js插入到html页面

    浏览器就直接看到了对象转变成的字符串

    Convertor:如 Gson,Jackson,FastJson

    1. @RequestMapping("/data")
    2.    @ResponseBody      //不拿页面
    3.    Object data(){
    4.        //拿页面
    5.        System.out.println("data-------调用");
    6.         return new Book(2,"物语","尼科尔",200);
    7.   }

    book对象转换成字符串:

    1.tostring()

    2.json

    1. @RequestMapping("/data")
    2.    @ResponseBody      //不拿页面
    3.    Object data(){
    4.        //拿页面
    5.        System.out.println("data-------调用");
    6.        Book book = new Book(2, "物语", "尼科尔", 200);
    7.        System.out.println(book);
    8.        return book;
    9.   }

    ######

    3.7.3 重定向

    涉及面试题:

    重定向:服务器叫浏览器去访问另外一个url

    response.sendRedirect("另一个url");

    3.7.3.1.相对路径

    相对于浏览器地址栏

     

    1. package com.hqyj.controller;
    2. import org.springframework.stereotype.Component;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.ui.Model;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. import javax.xml.ws.RequestWrapper;
    10. @Controller
    11. @RequestMapping("/book")
    12. public class BookController {
    13.    @RequestMapping("/work")
    14.    String work(HttpServletRequest request, Model model, HttpServletResponse response, HttpSession session){
    15.        System.out.println("work----干活");
    16.        String name = "潘江";
    17.        model.addAttribute("name",name);
    18.        return "redirect:add";     //重定向
    19.           //相对路径,相对于浏览器当前路径的地址栏
    20.   }
    21.    @RequestMapping("/add")
    22.    String add(){
    23.        System.out.println("add----访问");
    24.        return "book/add";
    25.   }
    26. }

    3.7.3.2 根路径

    根路径方式,spring项目会帮我们加上项目虚拟路径

    从当前路径来看

    根路径为:

    http://localhost:8080/studyWebproject_war_exploded/book/work

    根路径重定向为: 抹掉项目名

    http://localhost:8080/book/add

     

    4. conbertor转换器

    conbertor 转换器:jackson(三个jar,版本配对)、gson谷歌(一个jar包)、fasthson阿里

    有接口,spring会自动再jar中去寻找实现类

    这里使用了gson谷歌

     

    1.    @RequestMapping("/data")
    2.    @ResponseBody      //不拿页面
    3.    Book data(){
    4.        //拿页面
    5.        System.out.println("data-------调用");
    6.        Book book = new Book(2, "物语", "尼科尔", 200);
    7.        System.out.println(book);
    8.        return book;
    9.   }

     

    5.全分离开发方式

    5.1.不分离开发方式

     

    转变为:

    5.2.全分离开发方式

     

    6、日志

    6.1.动态查找机制

    mybatis:log4j

    不好用,不会输出提示,原因是

    spring:

    一旦有log4j的jar包,spring就用的是log4j的jar包,但是现在找不到log4j的配置文件,所以控制台没有输出

    解决方法:

    6.2.spring使用common-logging

    1.强制让spring使用common-logging 加两个文件

     

     

     

    6.3.log4j

    2.把log4j的配置文件拷贝进来(不建议用这个,不好排错)

    拷贝一个log4j.properties拷贝进来

     

     

     

    6.4.logback

    spring5使用logback日志系统

    7、分层

    A------------>B(B封装分层为B和C)

    A------------>B------------>C

    A------------>B------------>C------------>D

    这种情况容易出现可读性的问题:可读性不能太深

    7.1.三层结构

    A------------>B------------>C (可读性稍微要好一点,可读性客观)

    Controller层-------->service层---------->mapper/Dao

    Controller:控制层

    service层: 业务逻辑层

    需要接口实现

    为了松耦合(vehicle,car)

    mapper/Dao: 数据访问层

    例如:

    x-----调用------> T

    y-----调用------> T

    z-----调用------> T

    如果将来T发生改变,x\y\z也会发生变化,改动就发生了变化,需要维护

     

     

     发生了乱码

    7.2.多层结构

     

    7.3.中文乱码问题

     

     

     

     

    解决方法:

    7.3.1.解决 POST 请求乱码问题:

    (1)在 web.xml 中配置⼀个 CharacterEncodingFilter 过滤器,设置成 utf-8;

       
    1.  <filter>
    2.        <filter-name>characterEncodingFilterfilter-name>
    3.        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    4.        <init-param>
    5.            <param-name>endcodingparam-name>
    6.            <param-value>UTF-8param-value>
    7.        init-param>
    8.        <init-param>
    9.            <param-name>forceEncodingparam-name>
    10.            <param-value>trueparam-value>
    11.        init-param>
    12.    filter>
    13. <filter-mapping>
    14.    <filter-name>characterEncodingFilterfilter-name>
    15.    <url-pattern>/*url-pattern>
    16. filter-mapping>

    (2)再方法上放加上生成器和字符集,json格式,只能单个设置

    1. @RequestMapping(value = "/a2",produces = "application/json;charset=utf-8")
    2.    @ResponseBody
    3.    String a2(){   //返回字符串,默认,消息转换器MeessageConvertor
    4.        return "a2字符串";
    5.   }

    (3)使用mvc:message-converters

    1.    
    2.    <mvc:annotation-driven>
    3.        <mvc:message-converters>
    4.            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    5.            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
    6.                <property name="supportedMediaTypes">
    7.                    <list>
    8.                        <value>text/plain;charset=utf-8value>
    9.                        <value>text/html;charset=UTF-8value>
    10.                    list>
    11.                property>
    12.            bean>
    13.        mvc:message-converters>
    14.    mvc:annotation-driven>

    7.3.2 GET 请求中⽂参数出现乱码解决⽅法有两个:

    (1)修改 tomcat 配置⽂件添加编码与⼯程编码⼀致,如下:

    1. redirectPort

    2)对参数进⾏重新编码:

    String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

  • 相关阅读:
    Vue2与Vue3区别01
    私人社交群组平台Zusam
    鸿蒙智联开发者平台项目的理解介绍
    python基础
    java垃圾回收-三色标记法
    【普通人解题】leetcode 62. 不同路径
    部署SeaTunnel单节点Standalone 模式环境
    k8s 增加 node 节点
    Spring Boot(一)
    linux多线程例程
  • 原文地址:https://blog.csdn.net/weixin_46048259/article/details/126449171