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();}
}

未完待续…

spring入门总结相关推荐

  1. IDEA下——Spring入门程序

    创建一个Maven的项目,我的项目结构如下: 在pom文件里写下需要导入的依赖: <?xml version="1.0" encoding="UTF-8" ...

  2. spring入门详细教程(五)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  3. Spring入门详细教程(四)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  4. Spring入门详细教程(三)

    前言 本篇紧接着spring入门详细教程(二),建议阅读本篇前,先阅读第一篇和第二篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/101 ...

  5. Spring入门详细教程(二)

    前言 本篇紧接着spring入门详细教程(一),建议阅读本篇前,先阅读第一篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/1016553 ...

  6. Spring入门介绍:

    Spring入门介绍 Spring诞生: 创建Spring的目的就是用来替代更加重量级的的企业级Java技术 简化Java的开发 基于POJO轻量级和最小侵入式开发 通过依赖注入和面向接口实现松耦合 ...

  7. Spring入门5.事务管理机制

    Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...

  8. “Spring入门”教程系列

    大家好, 我很高兴向您介绍"Spring入门"教程系列! 这是一系列文章,最初由我们的JCG合作伙伴 Michal Vrtiak在vrtoonjava博客上撰写 . 本系列中将逐步 ...

  9. Spring入门与常用配置

    什么是Spring Spring:SE/EE开发的一站式框架. 一站式框架:有EE开发的每一层解决方案.  WEB层 :SpringMVC   Service层 :Spring的Bean管理,Spri ...

  10. Spring入门示例及相关概念介绍

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Spri ...

最新文章

  1. 2022-2028年中国橡胶板的制造行业发展战略规划及投资方向研究报告
  2. XPath与多线程爬虫
  3. Conficker蠕虫新动作 P2P更新5月份关闭
  4. JAVA开发者的Golang快速指南
  5. C++11:forward及完美转发
  6. linux rm 某个时间以前,(转)linux的一个find命令配合rm删除某天前的文件
  7. adprw指令通讯案例_超实用,非常典型的Modbus通讯项目案例,三分钟学会
  8. fiddler打开后 浏览器就上不了网的解决方法
  9. 八类网线和七类网线的区别_Cat8 八类网线与超五类网线、六类网线、超六类网线及七类/超七类网线的区别...
  10. Carthage的安装和使用
  11. 计算机邮件合并应用测试怎么做,四大实例干货:word邮件合并功能步骤详解教程...
  12. 如何提高自己的工作能力 高效工作方法是绝效
  13. h0004.双倍 (10 分)
  14. 如何在Excel中将多个单元格中的文本合并到一个单元格中
  15. 一级建造师可以跨省考试吗?
  16. VB6.0操作WPS2019
  17. 调整Ubuntu16.04屏幕分辨率
  18. 原画 机器人总动员_《机器人瓦力》导演执导 科幻史诗巨制《火星上的约翰·卡特》首支震撼预告...
  19. 探索STM32F407ZET6,全套设计资料,包含原理图
  20. Leetcode_6_Z字形变换_模拟

热门文章

  1. 基于计算机底层基础设计一个高性能的单机管理主机的心跳服务
  2. ui界面设计做什么:ui设计具体是什么
  3. html怎么吧图片设置成背景音乐,如何把照片做成视频并添加音乐
  4. Python 小技之繁花盛开
  5. 基于微信云开发的商家转账至零钱
  6. matlab 前向欧拉法,前向后项差分和显式隐式欧拉法
  7. Noisy Channel Language Model Prompting for Few-Shot Text Classification
  8. FANUC机器人动作指令的定位类型FINE和CNT详解
  9. OU Graphics 建筑后期悬挂植物制作PS教程
  10. (实测可用)STM32CubeMX教程-STM32L431RCT6开发板研究(ADC)