Spring

Spring

Spring概念

轻量级的开源javaEE框架

轻量级,引入的jar包小。不依赖与其他的组件自己可以单独使用。

可以解决开发的复杂性

两个核心

IOC:控制反转,把创建对象过程交给Spring进行管理。

AOP:面向切面,不修改源代码进行功能增强。

Spring特点:

方面结构,简化开发

Aop编程支持

方面程序测试

可以整个其他各种框架。

方便事务操作。

入门案例

Name:spring
Repository Path:release/org/springframework/spring/
URL to file:https://repo.spring.io/artifactory/release/org/springframework/spring/
Created:30-09-19 09:06:32 +00:00
实施:

spring最基本的四个组成部分beans、context、core、expression,这四个基本包。

在使用时需要在增加commons-logging.jar文件;如果没有logging包的话,@test不能使用。

package com.company.testdemo;
import com.company.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
//如果没有logging包的话,@test不能使用
    @Test
    public void testAdd(){
        //1 加载spring配置文件
        ApplicationContext context=
                new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象
        User user=context.getBean("user", User.class);
        System.out.println(user);
        user.add();

    }
}
package com.company;

public class User {
    public void add(){
        System.out.println("add...........");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    配置User对象创建-->
    <bean id="user" class="com.company.User"></bean>
</beans>

IOC

什么是IOC

控制反转,把对象创建和对象之间的调用过程,交给spring进行管理。使用IOC的目睹是为了耦合度的降低。做的入门案例就是IOC的实现。

IOC的底层原理:

xml解析、工厂模式,反射

说明

当前有两个类分别叫UserService{execute(){}}和UserDao{add(){}},例如当前execute方法要调用add方法,传统的方法是在execute方法中new一个UserDao然后调用add方法,这个方法耦合度太高,如dao的路径变化了execute里面的调用也需要变化。*可以使用工厂模式:再增加一个UserFactory工厂类在工厂类中设置一个public static UserDao getDao(){return new UserDao()};方法。这是在execute方法中可以通过工厂类的getDao方法进行add方法的调用。**但是此时还是有比较高的耦合度的。但是相对于原始方法要好。**而IOC则可以是耦合度更低。

IOC:
IOC过程:

第一步:xml配置文件

<!--    配置User对象创建-->
    <bean id="user" class="com.company.User"></bean>

第二步:有service类和dao类,创建工厂类

class UserFactory{
    public static UserDao getDao(){
    	String classValue=classs属性值;//1、xml解析
        Class clazz=Class.forName(classsValue);//2 通过反射创建对象
        return (UserDao)clazz.newInstance();
    }
}
IOC接口:

IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。Spring提供IOC容器实现两种方式:(两个接口)BeanFactory和ApplicationContext

BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用。加载配置文件的时候不会创建对象,在获取对象(使用)才去创建对象

ApplicationContext:BeanFactory接口的子接口,提供更多更强大的接口,提供更多更强大的功能,一般由开发人员进行使用。加载配置文件时候会把在配置文件对象进行创建。在服务器启动的时候就创建,而不是在操作的时候创建。

ApplicationContex接口有实现类。

在这里插入图片描述

IOCbean管理

什么是bean管理:

spring创建对象,spring注入属性。

bean管理有两种操作方式:

基于xml配置文件方式实现。

基于注解方式实现。

IOC操作bean管理
1、基于xml方式创建对象
  1. 在spring配置文件中使用bean标签,标签中添加对应的属性就可以实现对象创建。
  2. 在bean标签中有很多属性:
    1. id属性:给class对象取一个别名以作为唯一的标识
    2. class属性:类的全路径(包类路径)
  3. 创建对象时候默认也是执行无参数构造方法完成对象创建
2、基于xml方式注入属性
  1. DI:以来注入,注入属性。

    1. 使用set方法进行注入

      1. 创建类:定义属性和对应的set方法。

        package com.company;
        
        /**
         * 演示使用set方法进行属性注入
         */
        public class Book {
        //    public Book(String bname) {
        //        this.bname = bname;
        //    }
            private String bname;
            private String bauthor;
        
            public void setBname(String bname) {
                this.bname = bname;
            }
            public void setBauthor(String bauthor) {
                this.bauthor = bauthor;
            }
        
        public void testDemo(){
            System.out.printf(bname+"::"+bauthor);
            }
        }
        
      2. 在spring配置文件配置对象创建,配置属性注入

        <!--    set方法注入属性-->
            <bean id="book" class="com.company.Book">
        <!--        使用property完成属性注入
                    name:类里面属性名称
                    value:像属性注入的值-->
                <property name="bname" value="易筋经"></property>
                <property name="bauthor" value="达摩老祖"></property>
            </bean>
        
      3. 测试

        @Test
        public void testBook1(){
            //1 加载spring配置文件
            ApplicationContext context=
                    new ClassPathXmlApplicationContext("bean1.xml");
            //2 获取配置创建的对象
            Book book=context.getBean("book", Book.class);
            System.out.println(book);
            book.testDemo();
        }
        

      有参构造注入(快捷键alt+ins)

    2. 在spring配置文件中进行配置

      <!--    有参数构造注入属性-->
          <bean id="orders" class="com.company.Orders">
              <constructor-arg name="oname" value="abc"></constructor-arg>
              <constructor-arg name="address" value="China"></constructor-arg>
          </bean>
      
  2. p名称空间注入(了解)

    1. 使用p名称空间注入,可以简化基于xml配置方式

      1. 第一步;添加p 名称空间在配置文件中
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:p="http://www.springframework.org/schema/p"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      

      第二步进行属性注入,在bean标签中进行操作

        <bean id="book" class="com.company.Book" p:bname="九阳神功" p:bauthor="无名氏"></bean>
      
3、IOC操作bean管理(xml注入其他类型属性)
  1. 字面量:null值

        <bean id="book" class="com.company.Book">
    <!--        使用property完成属性注入
                name:类里面属性名称
                value:像属性注入的值-->
            <property name="bname" value="易筋经"></property>
            <property name="bauthor" value="达摩老祖"></property>
    <!--        null值-->
            <property name="address"><null/></property>
        </bean>
    
  2. 注入属性外部bean

    1. 创建两个类service类和dao类。

      package com.company.dao;
      
      public class UserDaoImpl implements UserDao {
      
          @Override
          public void upadd() {
      
              System.out.println("dao updata...........");
          }
      }
      
    2. 在service调用到里面的方法。

      package com.company.service;
      
      import com.company.dao.UserDao;
      import com.company.dao.UserDaoImpl;
      
      public class UserService {
      
          private UserDao userDao;
          public void setUserDao(UserDao userDao){
              this.userDao=userDao;
          }
      
          public void add(){
              System.out.println("service add...........");
      
              userDao.upadd();
      
      //原始方式:创建UserDao对象
      //        UserDao userDao = new UserDaoImpl();
      //        userDao.upadd();
          }
      }
      
    3. 在Spring配置文件中进行配置。

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:p="http://www.springframework.org/schema/p"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <!--service和dao对象创建-->
          <bean id="userService" class="com.company.service.UserService">
      <!--        注入userDao对象
                  name属性值:类里面属性名称
                  ref属性:创建userDao对象备案标签id值-->
              <property name="userDao" ref="userDaoImpl"></property>
          </bean>
      
          <bean id="userDaoImpl" class="com.company.dao.UserDaoImpl"></bean>
      
      </beans>
      

      测试

      @Test
          public void testAdd(){
              //1、加载spring配置文件
              ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
              //2、获取配置创建的对象
              UserService userService=context.getBean("userService", UserService.class);
              userService.add();
          }
      
  3. 注入属性-内部bean

    1. 一对多关系:部门和员工

      package com.company.bean;
      /**
       * 部门类
       */
      public class Dept {
          private String dname;
      
          public void setDname(String dname) {
              this.dname = dname;
          }
          @Override
          public String toString() {
              return "Dept{" +
                      "dname='" + dname + '\'' +
                      '}';
          }
      }
      
    2. 一个部门有多个员工一个员工属于一个部门。部门是一,员工是多

      package com.company.bean;
      
      /**
       * 员工类
       */
      public class Emp {
          private String ename;
          private String genter;
      //员工属于某一个部门,使用对象形式表示
          private Dept dept;
          public void setEname(String ename) {
              this.ename = ename;
          }
      
          public void setGenter(String genter) {
              this.genter = genter;
          }
      
          public void setDept(Dept dept) {
              this.dept=dept;
          }
      
          public void add(){
              System.out.printf(ename+"::"+genter+"::"+dept);
          }
      }
      
    3. 在实体类之间表示一对多关系

    4. 在Spring配置文件中进行配置。

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      <!--    内部bean-->
          <bean id="emp" class="com.company.bean.Emp">
      <!--        设置两个普通属性对象-->
              <property name="ename" value="lucy"></property>
              <property name="genter" value="nv"></property>
      <!--        设置对象类型属性-->
              <property name="dept">
                  <bean id="dept" class="com.company.bean.Dept">
                      <property name="dname" value="保安部"></property>
                  </bean>
              </property>
          </bean>
      </beans>
      

      测试

      @Test
      public void testBean3(){
          //1、加载spring配置文件
          ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");
          //2、获取配置创建的对象
          Emp emp = context.getBean("emp",Emp.class);
          emp.add();
      }
      
  4. 注入属性:级联赋值

    更改Spring配置文件

    1. 写法1

      <!--    内部bean-->
      <bean id="emp" class="com.company.bean.Emp">
          <!--        设置两个普通属性对象-->
          <property name="ename" value="lucy"></property>
          <property name="genter" value="nv"></property>
          <!--        设置对象类型属性-->
          <property name="dept" ref="dept"></property>
      </bean>
      <bean id="dept" class="com.company.bean.Dept"><property name="dname" value="财务部"></property> </bean>
      
    2. 写法二:需要在emp类中增加getdept方法

      <!--    级联赋值-->
      <bean id="emp" class="com.company.bean.Emp">
          <!--        设置两个普通属性对象-->
          <property name="ename" value="lucy"></property>
          <property name="genter" value="nv"></property>
          <!--        设置对象类型属性-->
          
          <property name="dept.dname" value="jishubu"></property>
      
      </bean>
      
      public void setDept(Dept dept) {
          this.dept=dept;
      }
      
      public Dept getDept() {
          return dept;
      }
      
4、IOC操作bean管理(xml注入集合属性)
  1. 注入数组类型属性

    注入list集合类型属性

    注入Map集合类型属性

    1. 创建类,定义数组、list、map、set类型属性,生成对应set方法

      package com.company.collectiontype;
      
      import java.util.Arrays;
      import java.util.List;
      import java.util.Map;
      import java.util.Set;
      
      public class Stu {
          private String[] courses;
          private List<String> list;
          private Map<String,String> maps;
          private Set<String> sets;
      
          public void setCourses(String[] courses) {
              this.courses = courses;
          }
      
          public void setList(List<String> list) {
              this.list = list;
          }
      
          public void setMaps(Map<String, String> maps) {
              this.maps = maps;
          }
      
          public void setSets(Set<String> sets) {
              this.sets = sets;
          }
      
          public void test(){
              System.out.println(Arrays.toString(courses));
              System.out.println(list);
              System.out.println(maps);
              System.out.println(sets);
      
      
          }
      }
      
    2. 在spring配置文件进行配置

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:p="http://www.springframework.org/schema/p"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      
      <!--    1集合类型属性注入-->
          <bean id="stu" class="com.company.collectiontype.Stu">
      <!--        数组类型注入-->
              <property name="courses">
                  <array>
                      <value>java</value>
                      <value>SQL</value>
      
                  </array>
              </property>
      <!--        list类型注入-->
              <property name="list">
                  <list>
                      <value>张三</value>
                      <value>小三</value>
                  </list>
              </property>
      <!--        map类型属性注入-->
              <property name="maps">
                  <map>
                      <entry key="JAVA" value="java"></entry>
                      <entry key="PHP" value="php"></entry>
                  </map>
              </property>
              <!--        set类型属性注入-->
              <property name="sets">
                  <set>
                      <value>MySQL</value>
                      <value>Redis</value>
                  </set>
              </property>
          </bean>
      
      </beans>
      

      测试

      package com.company.testdemo;
      
      import com.company.collectiontype.Stu;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestSpring5Demo1 {
      
          @Test
          public void testCollection(){
              ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
              Stu stu=context.getBean("stu",Stu.class);
              stu.test();
          }
      }
      
  2. 在集合里面设置对象类型值

    <!--        注入list集合类型,值是对象-->
            <property name="courseList">
                <list>
                    <ref bean="course1"></ref>
                    <ref bean="course2"></ref>
                </list>
            </property>
            
        </bean>
    
    
    
        <bean id="course1" class="com.company.collectiontype.Course">
            <property name="cname" value="Spring5框架课程"></property>
        </bean>
        <bean id="course2" class="com.company.collectiontype.Course">
            <property name="cname" value="MyBatis框架课程"></property>
        </bean>
    
  3. 把集合注入部门提取出来

    1. 在spring配置文件中引入名称空间:util

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:p="http://www.springframework.org/schema/p"
             xmlns:util="http://www.springframework.org/schema/util"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util.xsd">
      
5、IOC操作bean管理(FactoryBean)
  1. Spring有两种类型bean,一种普通bean,另一种工厂bean(FactoryBean)

    1. 普通bean:在配置文件中定义bean类型就是返回类型

    2. 工厂bean:在配置文件定义bean类型可以和返回类型不一样

      1. 创建类,让这个类作为工厂bean,实现接口FactoryBean

        package com.company.factorybean;
        
        import com.company.collectiontype.Course;
        import org.springframework.beans.factory.FactoryBean;
        
        public class MyBean implements FactoryBean<Course>{
        
            //定义返回bean
            @Override
            public Course getObject() throws Exception {
                Course course= new Course();
                course.setCname("abc");
                return course;
            }
        
            @Override
            public Class<?> getObjectType() {
                return null;
            }
        
        }
        
      2. 实现接口里面的方法,在实现的方法中定义返回的bean类型

        <bean id="myBean" class="com.company.factorybean.MyBean"></bean>
        
        @Test
        public void testCollection3(){
            ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
            Course course=context.getBean("myBean", Course.class);
            System.out.println(course);
        }
        
6、IOC操作Bean管理(bean作用域)
  1. 在Spring里面,设置创建bean实例是单实例还是多实例

  2. 在spring里面,默认情况下,bean是单实例对象

    @Test
    public void testCollection2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book1 = context.getBean("book",Book.class);
        Book book2 = context.getBean("book",Book.class);
        //book.test();
        System.out.println(book1);
        System.out.println(book2);
    }
    

    输出结果:

    com.company.collectiontype.Book@7d20d0b
    com.company.collectiontype.Book@7d20d0b

  3. 如何设置单实例还是多实例

    1. 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例

    2. scope属性值

      1. 默认值:singleton,表示是单实例对象
      2. prototype,表示的是多实例对象

      代码:

      <!--    2 提取list集合类型属性注入使用-->
          <bean id="book" class="com.company.collectiontype.Book" scope="prototype">
              <property name="list" ref="booklist"></property>
          </bean>
      

      输出结果:

      com.company.collectiontype.Book@7d20d0b
      com.company.collectiontype.Book@77f1baf5

    3. singleton和prototype区别:

      1. singleton单实例,prototype多实例

      2. 设置scope值是singleton时,加载spring配置文件时候就会创建单实例对象

        设置scope值是prototype时,不是在加载spring配置文件时创建对象,在调用getbean方法时创建多实例对象。

7、IOC操作Bean管理(Bean生命周期)
  1. bean生命周期:

    1. 通过构造器创建bean实例(无参构造)

    2. 为bean的属性设置值和对其他bean引用(调用set方法)

    3. 调用bean的初始化方法(需要进行配置)

    4. bean可以使用了(对象获取到了)

    5. 当容器关闭时,调用bean的销毁的方法(需要进行配置销毁的方法)

          @Test
          public void test4(){
      //        ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
      //        Orders orders=context.getBean("orders", Orders.class);
      //        System.out.println("fouth 获取创建bean实例对象");
      //        System.out.println(orders);
      //        //手动让bean实例销毁
      //        ((ClassPathXmlApplicationContext)context).close();
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
              Orders orders=context.getBean("orders", Orders.class);
              System.out.println("fouth 获取创建bean实例对象");
              System.out.println(orders);
              //手动让bean实例销毁
              context.close();
      
          }
      
      package com.company.bean;
      
      public class Orders {
      
          public Orders() {
              
              System.out.println("first 执行无参数构造创建bean实例");
          }
      
          private String oname;
          public void setOname(String oname) {
              this.oname = oname;
              System.out.println("second 调用set方法设置属性值");
          }
      
          public void initMethod(){
              System.out.println("third 执行初始化的方法");
          }
      
          public void destoryMethod(){
              System.out.println("fifth 执行销毁的方法");
          }
      }
      
      <bean id="orders" class="com.company.bean.Orders" init-method="initMethod" destroy-method="destoryMethod">
          <property name="oname" value="youji"></property>
      </bean>
      
  2. bean的后置处理器,bean生命周期有七步

    1. 通过构造器创建bean实例(无参构造)

    2. 为bean的属性设置值和对其他bean引用(调用set方法)

    3. 把bean实例传递bean后置处理器的方法 postProcessBeforeInitialization

    4. 调用bean的初始化方法(需要进行配置)

    5. 把bean实例传递bean后置处理器的方法 postProcessAfterInitialization

    6. bean可以使用了(对象获取到了)

    7. 当容器关闭时,调用bean的销毁的方法(需要进行配置销毁的方法)

      package com.company.bean;
      
      public class Orders {
      
          public Orders() {
              
              System.out.println("first 执行无参数构造创建bean实例");
          }
      
          private String oname;
          public void setOname(String oname) {
              this.oname = oname;
              System.out.println("second 调用set方法设置属性值");
          }
      
          public void initMethod(){
              System.out.println("third 执行初始化的方法");
          }
      
          public void destoryMethod(){
              System.out.println("fifth 执行销毁的方法");
          }
      }
      
      package com.company.bean;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanPostProcessor;
      
      
      public class MyBeanPost implements BeanPostProcessor {
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
              System.out.println("把bean实例传递bean后置处理器的方法");
              return bean;
          }
      
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
              System.out.println("把bean实例传递bean后置处理器的方法");
              return bean;
          }
      }
      
      <bean id="orders" class="com.company.bean.Orders" init-method="initMethod" destroy-method="destoryMethod">
          <property name="oname" value="youji"></property>
      </bean>
      
      <bean id="myBeanPost" class="com.company.bean.MyBeanPost"></bean>
      
      @Test
      public void test5(){
      
          ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
          MyBeanPost myBeanPost=context.getBean("myBeanPost", MyBeanPost.class);
          System.out.println("fouth 获取创建bean实例对象");
          System.out.println(myBeanPost);
          //手动让bean实例销毁
          context.close();
      }
      
8、IOC操作Bean管理(XML自动装配)
  1. 什么是自动装配

    根据指定装配规则(属性名称或者属性类型),spring自动将匹配的属性值进行注入

  2. 演示过程,两者同理,不能有两个相同的类型

    <!--实现自动装配
    bean标签autowire;配置自动床配
    有两个属性值:
    byName:根据属性名称注入,注入值bean的id值和类属性名称一样
    byType:根据类型名称注入
    -->
        <bean id="emp" class="com.company.autowire.Emp" autowire="byName" >
        </bean>
        <bean id="dept" class="com.company.autowire.Dept"></bean>
    </beans>
    
    @Test
    public void test6(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean5.xml");
        Emp emp=context.getBean("emp", Emp.class);
    
        System.out.println(emp);
    
    
    }
    
9、IOC操作bean管理(外部属性文件)
  1. 直接配置数据库信息

    1. 配置德鲁伊连接池

    2. 引入德鲁伊连接池依赖jar包

      druid-1.2.9.jar

      <!--直接配置连接池-->
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
              <property name="url" value="jdbc:mydql://localhost:3306/userDb"></property>
              <property name="username" value="root"></property>
              <property name="password" value="root"></property>
          </bean>
      
  2. 外部属性文件配置数据库连接池

    1. 创建外部属性文件,properties格式文件,写数据库信息

      prop.driverClass=com.mysql.jdbc.Driver
      prop.url=jdbc:mysql;//3306/userDb
      prop.name=root
      prop.password=root
      
      <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
              <property name="driverClassName" value="${prop.driverClass}"></property>
          <property name="url" value="${prop.url}"></property>
              <property name="username" value="${prop.name}"></property>
              <property name="password" value="${prop.password}"></property>
          </bean>
      
10、IOC操作Bean管理(基于注解方式)
  1. 什么是注解

    1. 注解是代码特殊标记,格式:@注解名称(名称属性=属性值,属性名称=属性值…
    2. 使用注解,注解作用在类上面,方法上面,属性上面
    3. 使用注解目的:简化xml配置。
  2. Spring 针对bean管理中创建对象提供注解

    1. @Component
    2. @Service
    3. @Controller
    4. @Repository
    5. 以上实例可以来创建Bean实例
  3. 基于注解方式实现对象创建

    1. 引入依赖spring-aop.jar

    2. 开启组件扫描

      /**
       * 在注解里面value属性值可以省略不屑,默认值是类名称,首字母小写
       * UserService——userService
       */
      @Component(value = "userService")
      public class UserService {
          public void add(){
              System.out.println("service add...");
          }
      }
      
          @Test
          public void testCollection1(){
              ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
              UserService userService=context.getBean("userService",UserService.class);
              userService.add();
              System.out.println(userService);
          }
      }
      
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:p="http://www.springframework.org/schema/p"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      <!--    开启组件扫描 如果扫描多个包,多个包使用逗号隔开 扫描包上层目录-->
          <context:component-scan base-package="com.company"></context:component-scan>
      </beans>
      
      11、基于注解方式实现属性注入
      1. @Autowired:根据属性类型进行自动装配

        /**
         * 在注解里面value属性值可以省略不屑,默认值是类名称,首字母小写
         * UserService——userService
         */
        @Service
        public class UserService {
            //定义dao类型属性
            //不需要添加set方法
            //添加注入属性注解
        
            @Autowired//根据类型进行注入
            
            
            public void add(){
                System.out.println("service add...");
                userDao.add();
            }
        }
        
        public class UserDao{
        
            public void add(){
                System.out.println("dao add...");
        
            }
        }
        
            @Test
            public void testCollection1(){
                ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
                UserService userService=context.getBean("userService",UserService.class);
                userService.add();
                System.out.println(userService);
            }
        }
        
        <!--    开启组件扫描 如果扫描多个包,多个包使用逗号隔开 扫描包上层目录-->
            <context:component-scan base-package="com.company"></context:component-scan>
        
      2. @Qualifier:根据属性名称进行注入 Qualifier要和Autowired一起使用

        package com.company.testdemo.dao;
        
        public interface UserDao {
            public void add();
        }
        
        package com.company.testdemo.dao;
        
        import org.springframework.stereotype.Repository;
        
        @Repository(value = "userDaoImpl111")
        public class UserDaoImpl implements UserDao{
        
            public void add(){
                System.out.println("dao add...");
        
            }
        }
        
        package com.company.testdemo.service;
        
        import com.company.testdemo.dao.UserDaoImpl;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.stereotype.Repository;
        import org.springframework.stereotype.Service;
        
        
        /**
         * 在注解里面value属性值可以省略不屑,默认值是类名称,首字母小写
         * UserService——userService
         */
        @Service
        public class UserService {
            //定义dao类型属性
            //不需要添加set方法
            //添加注入属性注解
        
            @Autowired//根据类型进行注入
            @Qualifier(value = "userDaoImpl111")//Qualifier要和Autowired一起使用
            private UserDaoImpl userDao;
            public void add(){
                System.out.println("service add...");
                userDao.add();
            }
        }
        
        <!--    开启组件扫描 如果扫描多个包,多个包使用逗号隔开 扫描包上层目录-->
            <context:component-scan base-package="com.company"></context:component-scan>
        
        public class TestSpring5Demo1 {
        
            @Test
            public void testCollection1(){
                ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
                UserService userService=context.getBean("userService",UserService.class);
                userService.add();
                System.out.println(userService);
            }
        }
        
      3. @Resource:可以根据类型注入,可以根据名称注入

        package com.company.testdemo.dao;
        
        public interface UserDao {
            public void add();
        }
        
        package com.company.testdemo.dao;
        
        import org.springframework.stereotype.Repository;
        
        @Repository(value = "userDaoImpl111")
        public class UserDaoImpl implements UserDao{
        
            public void add(){
                System.out.println("dao add...");
        
            }
        }
        
        package com.company.testdemo.service;
        
        import com.company.testdemo.dao.UserDao;
        import com.company.testdemo.dao.UserDaoImpl;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.stereotype.Repository;
        import org.springframework.stereotype.Service;
        import javax.annotation.Resource;
        
        
        /**
         * 在注解里面value属性值可以省略不屑,默认值是类名称,首字母小写
         * UserService——userService
         */
        @Service
        public class UserService {
            //定义dao类型属性
            //不需要添加set方法
            //添加注入属性注解
        
        //    @Autowired//根据类型进行注入
        //    @Qualifier(value = "userDaoImpl111")//Qualifier要和Autowired一起使用
        //    private UserDaoImpl userDao;
        
            //@Resource这个注解位于import javax.annotation.Resource;这个包
            //@Resource//根据类型注入
            @Resource(name = "userDaoImpl111")
            private UserDao userDao;
        
            public void add(){
                System.out.println("service add...");
                userDao.add();
            }
        }
        
        @Test
        public void testCollection1(){
            ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
            UserService userService=context.getBean("userService",UserService.class);
            userService.add();
            System.out.println(userService);
        }
        
        <!--    开启组件扫描 如果扫描多个包,多个包使用逗号隔开 扫描包上层目录-->
            <context:component-scan base-package="com.company"></context:component-scan>
        
      4. @Value:普通类型属性值的注入

        //service层
        @Value(value = "abc")
        private String name;
        
    3. 完全注解开发

      1. 创建配置类,替代xml配置文件

        package com.company.testdemo.config;
        
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
        
        @Configuration//作为配置类,替代xml配置文件
        @ComponentScan(basePackages = {"com.company"})
        public class SpringConfig {
        
        }
        
        
        @Test
        public void testService2(){
            ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService=context.getBean("userService",UserService.class);
            userService.add();
            System.out.println(userService);
        }
        

AOP

1、什么是AOP

面向几面变成,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

不通过修改源代码方式添加新功能而是通过权限判断模块。

2、AOP原理

package com.company.testdemo;

public interface UserDao {
    public int add(int a,int b);
    public String updata(String id);
    
}
package com.company.testdemo;



public class UserDaoImpl implements UserDao {

    @Override
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public String updata(String id) {
        return id;
    }
}
package com.company.testdemo;

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

public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfaces={UserDao.class};
//        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                return null;
//            }
//        });
        UserDaoImpl userDao=new UserDaoImpl();
        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
    }
}
//创建代理对象
class UserDaoProxy implements InvocationHandler{

    //1、把创建的是是谁的代理对象把谁传递过来
    //有参构造
    Object obj;
    public UserDaoProxy(Object obj)
    {
        this.obj=obj;
    }
    //蹭墙的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //方法之前
        System.out.println("before:"+method.getName()+":Parameter:"+ Arrays.toString(args));

        //被增强的方法执行
        Object res=method.invoke(obj,args);

        //方法之后
        System.out.println("after..."+obj);
        return res;
    }
}

JDBC Template

事务管理

Spring新特性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值