spring入门总结

spring入门总结

    • 一、spring介绍
      • 1、spring是什么
      • 2、理念:
      • 3、Spring优点:
      • 4、缺点
      • 5、主要内容:
    • 二、IOC&DI
      • 1、使用IOC创建对象的三种方法
        • a、无参构造方法创建
        • b、通过有参构造方法来创建
        • c、通过工厂方法来创建对象
      • 2、配置文件详解
      • 3、依赖注入DI
      • 4、bean的作用域和自动装配
      • 5、静态代理
      • 6、动态代理
    • 三、AOP
      • 1、使用spring实现aop的方式

一、spring介绍

1、spring是什么

spring: 春天; --给软件行业带来了春天。
Spring是一个 轻量级的DI和AOP容器框架。

说它轻量级有一大部分原因是相对与EJB的(虽然本人从没有接触过EJB的应用),重要的是,Spring是非侵入式的(所谓非侵入式就是远程调试 而不植入,spring不再用new的方式来创建对象,而是使用依赖注入的方式),基于spring开发的应用一般不依赖于spring的类。

2、理念:

使现有技术更加实用。本身是大杂烩整合现有的框架技术。

3、Spring优点:

  1. 使用Spring的IOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑
  2. 可以提供众多服务,事务管理,WS等。
  3. AOP的很好支持,方便面向切面编程。
  4. 对主流的框架提供了很好的集成支持,如hibernate,Struts2,JPA等
  5. Spring DI机制降低了业务对象替换的复杂性。
  6. Spring属于低侵入,代码污染极低。
  7. Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部

方便解耦,简化开发:
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
IOC容器–控制反转:
Spring是个容器,因为它包含并且管理应用对象的生命周期和配置。
aop面向切面编程:
Spring提供面向切面编程,可以方便的实现对程序权限拦截、运行监控等功能。
对事物的支持:
如对象的创建、销毁、回调等
对框架的支持:
Spring作为一个框架,提供了一些基础功能,(如事务管理,持久层集成等),使开发人员更专注于开发应用逻辑。
。。。

4、缺点

  1. jsp中要写很多代码、控制器过于灵活,缺少一个公用控制器
  2. Spring不支持分布式,这也是EJB仍然在用的原因之一。

首先Spring 是一个框架,使用Spring并不代表代码质量的提高,就像盖房子选择用上海的地皮还是北京的地皮一样,房子质量与土地所在的城市无关,与房子的具体设计方案和选料有关。

使用Spring 等框架可以简化很多基础性的工作,配置好后可以方便构建业务应用。

框架使用多了会有局限的感觉,像小鸟被套在笼子里,无法飞出去,虽然在笼子里面吃喝不愁。目前编程的门槛越来越低,诸多开源框架广泛传播,几乎没有什么技术门槛,会配置就会编程,而一个好的DBA对软件性能会有很大提高,软件的核心逻辑最终会转移到对数据库的操作上

5、主要内容:

在这里插入图片描述

二、IOC&DI

控制反转IOC(inversion of control)依赖注入DI(Dependency Injection) 一个概念,具体的讲,当一个角色需要另外一个角色协助的时候,在传统的程序设计中,通常有调用者来创建被调用者的实例。但是在spring中创建被调用者将不再有调用者完成,因此叫控制反转。创建被调用对象有Spring来完成,在容器实例化对象的时候主动的将被调用者(或者说它的依赖对象)注入给调用对象,因此又叫依赖注入。

特点:
对象由原来程序本身创建,变为了程序接收对象。
程序猿主要精力集中于业务实现。
实现了service和dao的解耦工作。service层和dao层实现了分离,没有直接的依赖关系。
如果dao的实现发生改变,应用程序本身不用改变。

下面创建第一个实例:
准备工作: idea配置
现在很多教程的都是MyEclipse编程,可能本人比较懒,所以直接用idea

创建Maven,创建一个web模板:
在这里插入图片描述
选好文件存放位置。
在这里插入图片描述
2020版本的idea,不用手动导包,进去它直接执行导包操作。

等待一段时间后~

在这里插入图片描述
resources下创建一个xml,名字自己取
在这里插入图片描述
OK,现在编写第一个spring程序

写一个xml,一般他会自动生成,只要把第6、7行写进去就行了

<?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就是java对象 由spring来创建管理--><bean name="hello" class="spring02_ioc.test.bean.hello"><property name="name" value="昀离君"/></bean>
</beans>

写一个hello.java

package spring02_ioc.test.bean;public class hello {public hello(){System.out.println("hello被创建");}private String name;public  void setName(String name){this.name = name;}public  void show(){System.out.println("hello" +name);}
}

写一个test.java

package spring02_ioc.test;import spring02_ioc.test.bean.hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {//解析applicationContext.xml文件生成相应的bean对象ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");hello hello =  (hello)context.getBean("hello");hello.show();}
}

运行test,得到下面结果:
在这里插入图片描述

那么,接下来思考?
hello对象是谁创建的?
hello对象属性是怎样设置的?
hello对象是由spring容器创建的。
hello对象属性是spring容器来设置的。

这个过程就叫控制反转:
控制内容: 指谁来控制对象的创建;传统的应用程序对象的创建是由程序本身控制的。使用spring后,是由spring来创建对象的。
反转: 正转指程序来创建对象,反转指程序本身不创建对象,而变为被动的接收对象。
总结: 以前对象是由程序本身来创建,使用spring后,程序变为被动接收spring创建好的对象。

控制反转 == 依赖注入

1、使用IOC创建对象的三种方法

a、无参构造方法创建

User.java

package spring04_ioc3.vo;public class User {public User(){System.out.println("User的无参构造方法");}private String name;public void setName(String name) {this.name = name;}public void show(){System.out.println("name" + name);}
}

bean.xml

<bean id="user" class="spring04_ioc3.vo.User"><property name="name" value="昀离君"></property></bean>

Test.java

package spring04_ioc3.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring04_ioc3.vo.User;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");user.show();}
}

b、通过有参构造方法来创建

User.java

package spring04_ioc3.vo;public class User {public User(String name){super();this.name = name;}private String name;public void show(){System.out.println("name" + name);}
}

bean.xml配置(有三种)

  1. 根据参数的下标来设置

    <bean id="user" class="spring04_ioc3.vo.User"><!--index指构造方法参数下标从0开始--><constructor-arg index="0" value="小昀离君"/>
    </bean>
    
  2. 根据参数名称来设置

    <bean id="user" class="spring04_ioc3.vo.User"><!--name指参数名--><constructor-arg name="name" value="小昀离君"/>
    </bean>
    
  3. 根据参数类型设置

    <bean id="user" class="spring04_ioc3.vo.User"><!--name指参数名--><constructor-arg type="java.lang.String" value="小昀离君"/>
    </bean>
    

Test.java

package spring04_ioc3.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring04_ioc3.vo.User;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)ac.getBean("user");user.show();}
}

c、通过工厂方法来创建对象

  1. 静态工厂
    UserFactory.java

    public class UserFactory {public static User newIstance(String name){return new User(name);}
    }
    

    bean.xml配置

    <bean id="user" class="spring04_ioc3.factory.UserFactory" factory-method="newIstance"><constructor-arg index="0" value="凡一"/>
    </bean>
    
  2. 动态工厂
    UserDynamicFactory.java

    public class UserDynamicFactory {public User newIstance(String name){return new User(name);}
    }
    

    bean.xml配置

    <bean id="userFactory" class="spring04_ioc3.factory.UserDynamicFactory"/><bean id="user" factory-bean="userFactory" factory-method="newIstance"><constructor-arg index="0" value="凡一"/>
    </bean>
    

2、配置文件详解

  1. alias:为bean设置别名,可以设置多个别名

    	<!--设置别名--><alias name="user" alias="user1 "/>
    
  2. bean的配置

    id是bean的标识符 要唯一 如果没有配置id,name默认标识符

    如果配置了id,又配置了name,那么name是别名

    name可以设置多个别名 分隔符可以是空格、逗号、分好等

    class是bean的全限定名= 包名 + 类名

    如果不配置id,和name 那么可以根据applicationContext.getBean(Class)获取对象

    <!--id是bean的标识符 要唯一 如果没有配置id,name默认标识符如果配置了id,又配置了name,那么name是别名name可以设置多个别名 分隔符可以是空格、逗号、分好等class是bean的全限定名= 包名 + 类名如果不配置id,和name 那么可以根据applicationContext.getBean(Class)获取对象--><bean id="h1" name="hello h2,h3;h4" class="spring02_ioc.test.bean.hello"><property name="name" value="小凡一"/></bean>
    
  3. 团队合作通过import来实现

    <import resource="entity.xml"/>
    

3、依赖注入DI

  1. 依赖注入—dependency injection
    依赖: 指bean对象创建依赖容器,bean对象的依赖资源
    注入: 指bean对象依赖的资源由容器来设置和装配

  2. spring注入—构造器注入
    见IOC创建对象

  3. spring注入——setter注入 (重点)
    要求被注入的属性必须有set方法。set方法的方法名由set+属性首字母大写。如果属性是Boolean 没有get方法 会返回is

    1. 常量注入

      <bean id="student" class="spring05_di.vo.Student"><property name="name" value="小小凡一"></property></bean>
      
    2. bean注入

      <bean id="addr" class="spring05_di.vo.Address"/><bean id="student" class="spring05_di.vo.Student"><property name="name" value="小小凡一"></property><property name="addr" ref="addr"/></bean>
      
    3. 数组注入

      <property name="books"><array><value>傲慢与偏见</value><value>战争与和平</value><value>盗梦者</value></array>
      </property>
      
    4. list注入

      <property name="hobbies"><list><value>羽毛球</value><value>乒乓球</value><value>篮球球</value><value>台球</value></list></property>
      
    5. map注入

      <property name="cards"><map><entry key="中国银行" value="4541534455"/><entry><key><value>建设银行</value></key><value>1531534631637</value></entry></map></property>
      
    6. set注入

      <property name="games"><set><value>lol</value><value>dota</value><value>王者荣耀</value><value>吃鸡</value></set></property>
      
    7. null注入

      <property name="wife"><null/></property>
      
    8. Properties注入
      需要在头文件中加入:

      xmlns:p="http://www.springframework.org/schema/p"
      
      <property name="info"><props><prop key="学号">202008092355</prop><prop key="sex"></prop><prop key="name">凡一</prop></props></property>
      
    9. p命名空间注入

      <!--p命名空间注入 属性依然要设置set方法--><bean id="user" class="spring05_di.vo.User" p:name="小朋友" p:age="12"/>
      
    10. c命名空间注入
      需要在头文件中加入:

      xmlns:c="http://www.springframework.org/schema/c"
      
      <!--c命名空间注入要求有对应参数的构造方法--><bean id="u1" class="spring05_di.vo.User" c:name="Elias" c:age="2000"/>
      

文件总合如下:
student.java

package spring05_di.vo;import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class Student {private String name;private Address addr;private String[] books;private List<String> hobbies;private Map<String, String> cards;private Set<String> games;private String wife;private Properties info;public void setName(String name) {this.name = name;}public void setAddr(Address addr) {this.addr = addr;}public void setBooks(String[] books) {this.books = books;}public void setHobbies(List<String> hobbies) {this.hobbies = hobbies;}public void setCards(Map<String, String> cards) {this.cards = cards;}public void setGames(Set<String> games) {this.games = games;}public void setWife(String wife) {this.wife = wife;}public void setInfo(Properties info) {this.info = info;}public void show(){System.out.println("name= " + name + "  address=" + addr.getAddress());System.out.print("books: ");for (int i = 0; i < books.length; i++){System.out.print(books[i] + "     ");}System.out.println();System.out.println("hobbies= " + hobbies);System.out.println("cards= " + cards);System.out.println("games= " + games);System.out.println("wife= " + wife);System.out.println("info= " + info);}
}

beans.xml配置

<?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:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--bean就是java对象 由spring来创建管理--><bean id="addr" class="spring05_di.vo.Address"><property name="address" value="广东河源"></property></bean><bean id="student" class="spring05_di.vo.Student"><property name="name" value="小小凡一"/><property name="addr" ref="addr"/><property name="books"><array><value>傲慢与偏见</value><value>战争与和平</value><value>盗梦者</value></array></property><property name="hobbies"><list><value>羽毛球</value><value>乒乓球</value><value>篮球球</value><value>台球</value></list></property><property name="cards"><map><entry key="中国银行" value="4541534455"/><entry><key><value>建设银行</value></key><value>1531534631637</value></entry></map></property><property name="games"><set><value>lol</value><value>dota</value><value>王者荣耀</value><value>吃鸡</value></set></property><property name="wife"><null/></property><property name="info"><props><prop key="学号">202008092355</prop><prop key="sex"></prop><prop key="name">凡一</prop></props></property></bean><!--p命名空间注入 属性依然要设置set方法--><bean id="user" class="spring05_di.vo.User" p:name="小朋友" p:age="12"/><!--c命名空间注入要求有对应参数的构造方法--><bean id="u1" class="spring05_di.vo.User" c:name="Elias" c:age="2000"/>
</beans>

Address.java

package spring05_di.vo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

User.java

package spring05_di.vo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

Test.java

package spring05_di.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring05_di.vo.Student;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");Student stu = (Student)ac.getBean("student");stu.show();}
}

Tesxt1.java

package spring05_di.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring05_di.vo.User;public class Test1 {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) ac.getBean("u1");System.out.println(user);}
}

4、bean的作用域和自动装配

bean的作用域:
scope指bean的作用域,在配置bean时,由scope来配置bean的作用域

singleton单例: 整个容器中只有一个对象实例 默认是单例
prototype原型 : 每次获取bean都产生一个新的对象
request: 每次请求时创建一个新的对象
session: 在会话的范围内是一个对象
global session: 只在portlet下有用,表示是application
application: 在应用范围中一个对象
书写格式示例:

<bean id="addr" class="spring05_di.vo.Address" scope="prototype">

注意: 在整合strut2和spring时,需要将action设为 scope=“prototype”。

自动装配——简化spring配置文件:
在配置bean时,可以配置bean的autowire属性,用于指定装配类型。

no : 不使用自动装配
ByName : 根据名称去查找相应的bean,如果有则装配上
byType : 根据类型进行自动装配 不用管bean的id,但是同一种类型的bean只能有一个 建议慎用
constructor: 当通过构造器注入实例化bean时 使用byType的方式装配构造方法

书写格式示例:

<bean id="addr" class="spring05_di.vo.Address" autowire="byName"/>

可以配置全局的自动装配类型,在头部添加default-autowire
示例:

<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" default-autowire="byName">

推荐不使用自动装配,使用annotation

5、静态代理

  1. 静态代理的角色分析:
    抽象角色----一般使用接口或者抽象类来实现。
    真实角色----被代理的角色。
    代理角色----代理真实角色,代理真实角色后一般会做一些附属操作。
    客户 ----使用代理角色来进行一些操作。

图例:
在这里插入图片描述

  1. 代码实现

    Rent.java—抽象角色

    public interface Rent {public void rent();
    }

    Host.java—真实角色

    public class Host implements Rent{public void rent(){System.out.println("房屋出租");}
    }
    

    Proxy.java—代理角色

    public class Proxy implements Rent{private Host host;public Proxy(){}public Proxy(Host host){this.host = host;}public void setHost(Host host) {this.host = host;}//租房public void rent(){seehouse();host.rent();fare();}//看房private void seehouse(){System.out.println("带房客看房");}//收中介费private void fare(){System.out.println("收中介费");}
    }

    Client.java—客户

    public class Client {public static void main(String[] args) {Host host = new Host();Proxy proxy = new Proxy(host);proxy.rent();}
    }

    结果:
    在这里插入图片描述

  2. 使用静态代理好处

    • 使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
    • 公共的业务由代理来完成----实现业务的分工
    • 公共业务发生扩展时变得更加集中和方便

    缺点:
    类多了----多了代理类。工作量变大了。开发效率变低了

6、动态代理

  1. 动态代理和静态代理的角色是一样的。

  2. 动态代理的代理类是动态生成的。

  3. 分为两类,一类基于接口动态代理和基于类的动态代理
    a.基于接口动态代理----jdk动态代理
    b.基于类的动态代理----cglib
    现在用javassist来生成动态代理。

    javassist介绍:
    Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态"AOP"框架。
    关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

  4. jdk动态代理----Proxy类和InvocationHandler接口

    InvocationHandler 是代理实例的 调用处理程序 实现的接口。

    每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法。

    invoke(Object proxy, Method method, Object[] args)
    //在代理实例上处理方法调用并返回结果
    

    在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
    参数:
    proxy - 在其上调用方法的代理实例
    method - 对应于在代理实例上调用的接口方法的Method实例。Method对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
    args - 是包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为null。基本类型的参数被包装在适当基本包装器类(如java.lang.Integer 或java.lang.Boolean)的实例中。
    返回:
    从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为null并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出ClassCastException。

实现:
ProxyInvoationHandler.java

package spring08_dynamicproxy.dynamicproxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyInvoationHandler implements InvocationHandler {private Object target; //目标对象---真实对象public void setTarget(Object target) {this.target = target;}public void setRent(Rent rent) {this.target = rent;}/*** 生成代理类*/public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);}/*** proxy是代理类* method 代理类的调用处理程序的方法对象*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {log(method.getName());Object result =  method.invoke(target, args);return result;}public void log(String methodName){System.out.println("执行" + methodName + "方法");}
}

Clinet.java

package spring08_dynamicproxy.dynamicproxy;import spring08_dynamicproxy.service.UserService;
import spring08_dynamicproxy.service.UserServiceImpl;public class Clinet {public static void main(String[] args) {UserService userService = new UserServiceImpl();ProxyInvoationHandler pih = new ProxyInvoationHandler();pih.setTarget(userService);UserService proxy = (UserService)pih.getProxy();proxy.add();}
}

UserService.java

package spring08_dynamicproxy.service;public interface UserService {public void add();public void update();public void delete();public void search();
}

UserService.java

package spring08_dynamicproxy.service;public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("增加用户");}@Overridepublic void update() {System.out.println("修改用户");}@Overridepublic void delete() {System.out.println("删除用户");}@Overridepublic void search() {System.out.println("查询用户");}}

注意:
一个动态代理一般代理某一类业务,一个动态代理可以代理多个类。

三、AOP

AOP(aspect oriented programming): Spring对面向切面编程提供了强有力的支持,通过它让我们将业务逻辑从应用服务(如事务管理)中分离出来,实现了高内聚开发(所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。),应用对象只关注业务逻辑,不再负责其它系统问题(如日志、事务等)。Spring支持用户自定义切面。

面向切面编程是面向对象编程的有力补充。面向对象编程将程序分成各个层次的对象,面向切面的程序将运行过程分解成各个切面。AOP是从运行程序的角度去考虑程序的结构,提取业务处理过程的切面,OOP是静态的抽象,AOP是动态的抽象,是对应用执行过程的步骤进行抽象,从而获得步骤之间的逻辑划分。

  1. aop在spring中的作用

    • 提供声明式服务(声明式事务)
    • 允许用户实现自定义切面
  2. aop:在不改变原有代码的情况下,增加新的功能。
    传统的编程模式:

    在这里插入图片描述
    aop的编程模式:
    在这里插入图片描述

  3. aop的好处:
    a、使用真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
    b、公共的业务由代理来完成-----实现业务的分工
    c、公共业务发生扩展时变得更加集中和方便

  4. 名词解释:
    关注点: 增加的某个业务。如日志、安全、缓存、事务等。
    切面(Aspect): 一个关注点的模块化
    通知(Advice): 在切面的某个特定的连接点上执行的动作
    织入(Weaving): 把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象

1、使用spring实现aop的方式

第一种实现方式-----通过springAPI来实现。

log.java—前置通知

	package spring09_aop1.log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class log implements MethodBeforeAdvice {public void log(){}/*** @param method    被调用方法对象* @param args  被调用的方法参数* @param target    被调用的方法目标对象*/@Overridepublic void before(Method method, Object[] args, Object target)throws Throwable {System.out.println(target.getClass().getName() + "的" + method.getName() + "方法被执行");}}

AfterLog.java

	package spring09_aop1.log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class AfterLog implements AfterReturningAdvice {/*** 目标方法执行后执行的通知** @param returnValue   返回值* @param method    被调用的方法对象* @param args   被调用的方法对象的参数* @param target    被调用的方法对象的目标对象* @throws Throwable*/@Overridepublic void afterReturning(Object returnValue, Method method,Object[] args, Object target)throws Throwable {System.out.println(target.getClass().getName() + "的" + method.getName() + "被成功执行,返回值是:" + returnValue);}}

目标类

	public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("增加用户");}@Overridepublic void update() {System.out.println("修改用户");}@Overridepublic void delete() {System.out.println("删除用户");}@Overridepublic void search() {System.out.println("查询用户");}}

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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userService" class="spring09_aop1.impl.UserServiceImpl"/><bean id="log" class="spring09_aop1.log.log"/><bean id="afterLog" class="spring09_aop1.log.AfterLog"/><aop:config><aop:pointcut expression="execution(* spring09_aop1.service.*.*(..))"  id="pointcut"/><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>

测试类:

	public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService)ac.getBean("userService");userService.add();}}

aop的重要性:
spring aop就是将公共业务(如日志、安全等)和领域业务结合。当执行领域业务时将会把公共业务加进来。实公共业务的重复利用。领域业务更纯粹,程序猿专注于领域业务。其本质还是动态代理。

第二种方式实现aop:自定义类来实现

log.java

	public class log {public void before(){System.out.println("---------方法执行前---------");}public void after(){System.out.println("---------方法执行前---------");}}

beans.xml

	<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="UserService" class="spring10_aop2.impl.UserServiceImpl"/><bean id="log" class="spring10_aop2.log.log"/><aop:config><aop:aspect ref="log"><aop:pointcut id="pointcut" expression="execution(* spring10_aop2.impl.*.*(..))"/><aop:before method="before" pointcut-ref="pointcut"/><aop:after method="after" pointcut-ref="pointcut"/></aop:aspect></aop:config></beans>

UserServiceImpl.java

	public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("---------添加用户数据----------");}@Overridepublic void delete() {System.out.println("----------删除用户数据----------");return;}}

UserService.java

	public interface UserService {public void add();public void delete();}```Test.java```javapublic class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService)ac.getBean("UserService");userService.delete();}}

第三种实现方法—通过注解来实现
log.java

package spring11_aop3.log;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class log {@Before("execution(* spring11_aop3.impl.*.*(..))")public void before(){System.out.println("---------方法执行前---------");}@After("execution(* spring11_aop3.impl.*.*(..))")public void after(){System.out.println("---------方法执行后---------");}@Around("execution(* spring11_aop3.impl.*.*(..))")public Object aroud(ProceedingJoinPoint jp) throws Throwable {System.out.println("环绕前");System.out.println("签名" + jp.getSignature());//执行目标方法Object result =  jp.proceed();System.out.println("环绕后");return result;}
}

如果idea输入注解@Aspect时,出现错误,原因是因为注解包没导进去,在pom.xml中加入下列这段(然后等一会儿,让idea下载完):

<!-- http://mvnrepository.com/artifact/org.aspectj/aspectjweaver --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.9</version></dependency><!-- http://mvnrepository.com/artifact/cglib/cglib --><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.2</version></dependency>

配置文件:

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="UserService" class="spring11_aop3.impl.UserServiceImpl"/><bean id="log" class="spring11_aop3.log.log"/><aop:aspectj-autoproxy/>
</beans>

UserService.java

package spring11_aop3.service;public interface UserService {public void add();public void delete();
}

UserServiceImpl.java

package spring11_aop3.impl;import spring11_aop3.service.UserService;public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("---------添加用户数据----------");}@Overridepublic void delete() {System.out.println("----------删除用户数据----------");return;}}

Test.java

package spring11_aop3.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring11_aop3.service.UserService;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService)ac.getBean("UserService");userService.delete();}
}

未完待续…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/250890.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Spring 入门

引自&#xff1a;http://www.ibm.com/developerworks/cn/java/wa-spring1/ Spring 系列: Spring 框架简介 Spring AOP 和 IOC 容器入门 2005 年 8 月 18 日 在这由三部分组成的介绍 Spring 框架的系列文章的第一期中&#xff0c;将开始学习如何用 Spring 技术构建轻量级的、强…

Spring入门须知

Hi ~o(*&#xffe3;▽&#xffe3;*)ブ大家好呀&#xff01; 我是【小阿飞_】&#xff0c;我又来给大家分享知识啦&#x1f61c; 今天分享的是spring入门需要理解的一些概念和一些基础的使用操作&#xff0c;有哪里讲解的不好还请大佬们评论区多多指点&#x1f61c; 本期精彩&…

Spring入门基础

目录 1.Spring的相关概念 2.Spring的核心与设计思想 3.Spring创建与使用 4.更简单地去使用Spring 5.Bean的作用域与生命周期 1.Spring相关概念 1.1 什么是Spring 我们通常所说的 Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个…

Spring入门程序

目录 一、Spring概述二、Spring的体系结构三、Spring的核心容器四、实现步骤 一、Spring概述 spring是当前主流的JavaWeb框架&#xff0c;它是为了解决应用开发复杂性问题而产生的。对于一个Java应用程序员来说&#xff0c;掌握spring框架的使用&#xff0c;是我们基本的一项技…

Spring入门这一篇就够了

前言 前面已经学习了Struts2和Hibernate框架了。接下来学习的是Spring框架…本博文主要是引入Spring框架… Spring介绍 Spring诞生&#xff1a; 侵入式概念 Spring是一种非侵入式的框架… 侵入式 非侵入式 松耦合 前面我们在写程序的时候&#xff0c;都是面向接口编程&#xff…

Spring入门,看这篇就够了

Spring入门&#xff0c;看这篇就够了 文章目录 Spring入门&#xff0c;看这篇就够了一、 初识Spring二、Spring Framework系统架构三、核心概念1.IoC&#xff08;inversion of control&#xff09;控制反转2.Bean3.DI&#xff08;dependency injection&#xff09;依赖注入 四、…

Spring 入门教程

Spring 入门教程 1、参考资料 尚硅谷-Spring5框架最新版教程&#xff08;idea版&#xff09;雷丰阳spring、springmvc、mybatis、spring一站式学习 项目地址&#xff1a;Oneby / spring-learn 2、Spring 概述 2.1、Spring 框架概述 Spring 是轻量级的开源的 JavaEE 框架 Sp…

一文学会Spring,Spring最简单的入门教程(万字好文)

1.Spring概述 1.1 Spring框架是什么 ​ Spring是与2003年兴起的一个轻量级的Java开发框架&#xff0c;它是为了解决企业应用开发的复杂性而创建的。Spring的核心是控制反转(IOC)和面向切面编程(AOP)。Spring是可以在Java SE/EE中使用的轻量级开源框架。 ​ Spring的主要作用…

阿里云的内容识别技术可以实现哪些场景下的智能化应用?

阿里云的内容识别技术可以实现哪些场景下的智能化应用&#xff1f; [本文由阿里云代理商[聚搜云]撰写]   随着人工智能技术的快速发展&#xff0c;阿里云借助自身的技术和资源优势&#xff0c;开发了一种名为“内容识别”的技术。这项技术能够高效、准确地识别出图片、视频、…

装饰器模式:实现类功能的动态扩展

一&#xff0c;简介 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许在不修改原有类结构的情况下&#xff0c;给一个对象动态添加额外的职责。通常情况下&#xff0c;扩展一个类的功能我们首先会想到用继承方式来实现&#xff0c…

One2Multi Graph Autoencoder for Multi-view Graph Clustering

One2Multi Graph Autoencoder for Multi-view Graph Clustering | Proceedings of The Web Conference 2020 (acm.org) 目录 Abstract 1 Introduction 2 Model 2.1 Overview 2.2 One2Multi Graph Convolutional Autoencoder Informative graph convolutional encoder M…

linux常见的二十多个指令

目录 一、指令的概念 二、28个常见的指令 ⭐2.1 ls指令 ⭐2.2 pwd指令 ⭐2.3 cd指令 ⭐2.4tree指令 ⭐2.5 mkdir指令 ⭐2.6 touch指令 ⭐2.7 rmdir指令 ⭐2.8 rm指令 ⭐2.9 clear指令 ⭐2.10 man指令 ⭐2.11 cp指令 ⭐2.12 mv指令 ⭐2.13 cat指令&#xff08;适…

Python画五角星(turtle初识)

Python可以做很多事情&#xff0c;主要归功于python下的各种模块。画图也不例外&#xff0c;通过简单地turtle模块&#xff0c;可以画出各种图案。 首先&#xff0c;使用python画图&#xff0c;需要安装turtle模块。在控制台输入pip install turtle执行 import turtle turtle.…

用python的turtle画五角星

最近开始学python&#xff0c;做作业的时候遇到画五角星并填充颜色。网上搜到的方法是画五条直线&#xff0c;但是作业要求的图形是这样 #用循环结构画五角星 import turtle from turtle import *turtle.delay(2) #定义一个画五角星的函数 def stardraw(start_position,side)…

Python turtle教程一:画箭头、矩形,五角星(亲测,可用)

Turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面坐标系中移动&#xff0c;从而在它爬行的路径上绘制了图…

初学Python画五角星

这学期开的Python课&#xff0c;之前学过java&#xff0c;c还有HTML5/css&#xff0c;不过感觉自己并不是学这些的料&#xff0c;这个是老师布置的作业&#xff0c;让我们自己画个图&#xff0c;就画了个简单的&#xff0c;心血来潮想写个博客&#xff0c;就直接上图了吧&#…

python画多层次五角星

此次用到海龟绘图函数——turtle&#xff0c;下面是程序中可能会用到的方法 forward() #前进 right() #右转 exitonclick() #绘制完退出Next ,show time! 1.创建一个python项目文件 2.分析单个五角星画法 我们默认每次画笔右转144度画五角星的一个角&#xff0c;那么画笔右转…

python画五角星

python画五角星 今天刚学python海龟画图&#xff0c;课堂作业画五角星&#xff0c;顺便分享给大家。 运行图片如下&#xff1a; 代码如下&#xff1a; # 以画布中心为中点&#xff0c;向右为X轴正方向&#xff0c;向上为Y轴正方向 import turtle turtle.setup(500, 500) #…

HTML5-画一个简单五角星

HTML5-画一个简单五角星 <!DOCTYPE HTML><html><body><canvas id"myCanvas" width"200" height"200" style"border:1px solid #c3c3c3;" mce_style"border:1px solid #c3c3c3;">Your browser does …

玩转Python之Turtle画五角星

Turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;下面就给大家分享用Turtle画五角星&#xff1a; #codingutf-8 import turtle import time turtle.pensize(5) turtle.pencolor(“yellow”) turtle.fillcolor(“red”) turtle.begin_fill() for _ in range(5…