Spring

Spring简介
1、 Spring:春天:给软件行业带来春天
2、 理念:使现有技术跟加实用,本身就是一种大杂烩,整合现有的框架技术
3、 Spring的优点
轻量级框架
IOC容器
AOP面向切面编程
对事物的支持
对框架的支持
百度百科:轻量级框架和重量级框架的区别
 
 
spring模块很复杂,使用了50%以上就是重量级


IOC(Inversion of Control,控制反转)
对象由原来的程序本身创建,变成了程序接收对象
程序员主要精力集中于业务实现
实现了每一层的解耦工作,实现了分离,没有直接依赖。
每一层的改变并不影响应用程序
案例1、
对象
public class User {
private String name;

public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public void show() {
System.out.println("hello"+name);
}
}
beans配置文件
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="hello" class="cn.mode.User">
  <property name="name" value="张三"/>
  </bean>
        </beans>
测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) cx.getBean("hello");
user.show();
}
}


提示:配置文件名字不像struts一样固定的。因为你可以自己写入,所以可以自己定义但是如果你没写入,它会默认去找ApplicationContext.xml
案例二、
对象的引用
DAO
public interface Userdao {
public void getUser();
}
重写接口类
public class UserDaoImpl implements Userdao{


@Override
public void getUser() {
// TODO Auto-generated method stub
System.out.println("调用User成功");
}


}


Biz类


public interface UserBiz {
public void getUser();
}
重写Biz类


public class UserBizImpl implements UserBiz {
private Userdao Userdao = null;

public Userdao getUserdao() {
return Userdao;
}


public void setUserdao(Userdao userdao) {
Userdao = userdao;
}


@Override
public void getUser() {
Userdao.getUser();

}


}




bean配置文件
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="userdao" class="cn.dao.UserDaoImpl" />
  <bean id = "userdaoT" class="cn.biz.UserBizImpl" >
  <property name="Userdao" ref="userdao"/>
  </bean>
        </beans>
测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");


UserBizImpl userbiz = (UserBizImpl)
 cx.getBean("userdaoT");
userbiz.getUser();
}
}




Bean的配置
第一种根据构造参数下标来设置
User类


public class User {
private String name;
public User(String name) {
this.name=name;
}
public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public void show() {
System.err.println("hello"+name);
}
}
测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) cx.getBean("user");
user.show();
}
}


bean配置文件
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id = "user" class="cn.mode.User" >
  <constructor-arg index="0" value="李四"></constructor-arg>
  </bean>
 </beans>
第二种按照参数类型进行配置
bean配置文件,其他文件不变
<?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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id = "user" class="cn.mode.User" >
  <constructor-arg type="java.lang.String" value="李四"></constructor-arg>
  </bean>
        </beans>
第三种按照参数名称进行配置
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id = "user" class="cn.mode.User" >
  <constructor-arg name="name" value="李四"></constructor-arg>
  </bean>
        </beans>


通过工厂方法来创建对象
静态工厂
User类
public class User {
private String name;
public User(String name) {
super();
this.name=name;
}
public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public void show() {
System.err.println("hello"+name);
}
}
工厂类
public class UserFactory {
public static User newInstance(String name) 
{
return new User(name);
}
}
测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) cx.getBean("user");
user.show();

}
}
bean配置文件
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id = "user" class="cn.UserFactory" factory-method="newInstance">
  <constructor-arg index="0" value="李四"></constructor-arg>
  </bean>
        </beans>
动态工厂
bean配置文件
<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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="UserFactory" class="cn.UserDynamicFactory"></bean>
  <bean id = "user" class="cn.UserDynamicFactory"
   factory-bean="UserFactory" factory-method="newInstance" >
  <constructor-arg index="0" value="李四"/>
  </bean>
        </beans>
工厂类
public class UserDynamicFactory {
public  User newInstance(String name) 
{
return new User(name);
}
}


测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) cx.getBean("user");
user.show();

}
}


配置文件的详解
1、 alias :为bean设置别名,可以设置多个别名
<!-- 设置别名 -->
  <alias name="user" alias="us"/>


2、 bean的配置
<!-- 
  id是bean的标识符,需要唯一,如果没有配置id,name是默认标识符,都配置了的话name为别名
  name可以设置多个别名,分隔符可以是空格逗号分号
  class是bean的全限定名=包名+类名
  如果不配置id和name那么可以根据
  ClassPathXmlApplicationContext(class)获取对象
   -->
    <bean id = "user" class="cn.UserDynamicFactory" name="u1,u2;u3 u4"></bean>
   


3、 团队协作通过import来实现
<import resource="spring/beans.xml"/>
依赖注入 DI
1、依赖注入
依赖:指bean对象创建依赖于容器。Bean对象依赖于资源
注入:指Bean对象依赖的资源由容器来设置装配
2、Spring注入—构造器注入
见IOC创建对象
3、Spring注入—setter注入
要求被注入的属性必须有set方法,set方法的方法名由set+属性首字母大写,如果是boolean没有get方法是is
a) 常量注入


<bean id="student" class="mode.vo.Student" > 
  <property name="name" value="张三丰"></property>
  </bean>
b) bean注入
<bean id="student" class="mode.vo.Student" > 
  <property name="mode" value="mode"></property>
  <property name="name" value="张三丰"></property>
  </bean>
  <bean id="mode" class="mode.vo.MOde"/>
c) 数组注入
<bean id="student" class="mode.vo.Student" > 
 
  <property name="arr">
  <array><value>一</value>
  <value>二</value>
  </array>
  </property>
  </bean>
d)list集合注入

<bean id="student" class="mode.vo.Student" > 
 
  <property name="hobbies">
  <list>
  <value>玩</value>
  <value>乐</value>
  </list>
  </property>
  </bean>
e)map注入
  </property><property name="cards">
  <map>
  <entry key="中国银行" value="149127348932174"/>
  <entry>
  <key><value>建设银行</value></key>
  <value>622710023478234234</value>
  </entry>
  </map>


f)set注入
<property name="games">
  <set>
  <value>lol</value>
  <value>dota</value>
  <value>cs1.6</value>
  <value>dnf</value>
  </set>
  </property>


g)null注入
<property name="wife"><null/></property>

h)properties注入
注入前先在头部文件添加
xmlns:p="http://www.springframework.org/schema/p"
在继续写
<property name="info">
  <props>
  <prop key="学号">2015052601</prop>
  <prop key="sex">男</prop>
  <prop key="name">小明</prop>
  </props>
  </property>


I)
P命名空间和C命名空间注入
<!-- p命名空间注入 属性依然要设置set方法 -->
 <bean id="user" class="cn.sxt.vo.User" p:name="风清扬" p:age="230"/>
 <!-- c命名空间注入要求有对应参数的构造方法 -->
 <bean id="u1" class="cn.sxt.vo.User" c:name="nico" c:age="16"/>
Bean的作用域


  <!-- bean的作用域    scope属性
    singleton单列  整个容器中只有一个对象实例 默认是单列
    prototype原型 每次获取bean都产生一个新的对象
    request 每次请求时创建一个新的对象
    session 在会话的范围内时一个对象
    global session 只在portlet下有用,表示是application
    application 在应用范围中一个对象
    -->
      <bean id="addr" class="cn.sxt.vo.Address" scope="request"/>


Bean自动装配
1、 scope指bean的作用域 在配置bean时,有scope属性来配置bean的作用域


  <!-- bean的作用域   
    singleton单列  整个容器中只有一个对象实例 默认是单列
    prototype原型 每次获取bean都产生一个新的对象
    request 每次请求时创建一个新的对象
    session 在会话的范围内时一个对象
    global session 只在portlet下有用,表示是application
    application 在应用范围中一个对象
    -->
       <bean id="mode" class="mode.vo.MOde" scope="">
   
在整合是需要将scope设置为prototype
2、 自动装配设置bean的autowire属性用于指定装配类型
  <?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" default-autowire="byName">
  <bean id="mysqlDao" class="cn.sxt.dao.impl.UserDaoMySqlImpl"/>
  <!-- autowire自动装配  简化spring配置
  no不使用自动装配
  byName 根据名称(set方法名来的)去查找相应的bean,如果有则装配上
  byType 根据类型进行自动装配  不用管bean的id.但是同一种类型的bean只能有一个。建议慎用
  constructor 当通过构造器 注入 实例化bean时 适用byType的方式 装配构造方法
  -->
  <bean id="service" class="cn.sxt.service.impl.UserServiceImpl" autowire="constructor"/>
</beans>




代理
静态代理
1、 静态代理角色分析:
抽象角色---一般使用接口或抽象类来实现
真实角色¬¬---被代理的角色
代理角色---代理真实角色---代理真实角色后一般会做出一些附属操作。
客户---使用代理角色
 
2、 代码实现
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(Host host) 
{
this.host=host;
}
public Host getHost() {
return host;
}
public void setHost(Host host) {
this.host = host;
}

public void seeHouse() {
System.out.println("带客户看房");
}
public void fare() {
System.out.println("收取中介费");
}
@Override
public void rent() {
// TODO Auto-generated method stub
seeHouse();
host.rent();
fare();
}
}
Client.java客户
public class Client {
public static void main(String[] args) {


Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}


3、 使用静态代理的好处
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
公共的业务由代理完成----实现业务的分工
公共业务发生拓展时变得更加集中和方便
缺点:
类多了---多了代理类。工作量变大了,开发效率降低了


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


4、 jdk动态代理---proxy类和invocationHandler接口
InvocationHandler 是代理实例的调用处理程序 实现的接口。 
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。 


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










Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。(超=父)
创建代理类的方法
static Object
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
          返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于: 
     Proxy.getProxyClass(loader, interfaces).
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 
Proxy.newProxyInstance 抛出 IllegalArgumentException,原因与 Proxy.getProxyClass 相同。 
参数: 
loader - 定义代理类的类加载器 
interfaces - 代理类要实现的接口列表 
h - 指派方法调用的调用处理程序 
返回: 
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口 
类加载器:java在执行某个类时,它需要将它的.class文件加载到虚拟机中,而这个过程将需要类加载器
实现:
public class ProxyInovationHandler implements InvocationHandler {

private Object rent;//可以写入任何对象

public Object getRent() {
return rent;
}


public void setRent(Object rent) {
this.rent = rent;
}
/**
* 生成代理类
*/
public Object getProxy() {
return Proxy.newProxyInstance(rent.getClass().getClassLoader(),
rent.getClass().getInterfaces(), this);
}
/**
* proxy是代理类
* Method是代理类的调用处理程序的方法对象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result= method.invoke(rent, args);
getMethodName(method.getName());
return result;
}
public void getMethodName(String name) {
System.err.println("执行"+name);
}
}
Client(客户)
public class Client {
public static void main(String[] args) {
Host host = new Host();//生成真实角色
ProxyInovationHandler pih = //生成代理角色
new ProxyInovationHandler();
pih.setRent(host);//将真实角色写入
Rent proxy = (Rent) pih.getProxy();//生成代理角色
proxy.Rent();
}
}
好玩的写法
public class Client {
public static void main(String[] args) {
ProxyInovationHandler ph = new ProxyInovationHandler();
ph.setRent(new ArrayList());
List list = (List) ph.getProxy();
list.add("1");
}
}






被代理的真实对象(随意写也行)
public class Host implements Rent{
public void Rent() {
System.out.println("房屋出租");
}
}




一个动态代理:一般代理一般代理某个类,动态代理可以代理很多个类
 


面向切面编程—AOP
1、 aop:aspet oriented programming 面向切面编程
2、 aop在Spring中的作用
提供声明式服务(声明式事物)
运行用户实现自定义切面
3、 aop:在不改变原有代码的情况下,增加功能
a) 传统的编程模式
























b) aop编程模式:横向的编程










4、 aop的好处
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
公共的业务由代理完成----实现业务的分工
公共业务发生拓展时变得更加集中和方便
5、 名词解释
a) 关注点:增加的某个业务,如安全,日志,事物,缓存等 上面事例的getMethodname()也是一种关注点
b) 切面:一个关注点的模块化,将关注点写成一个类(自己的理解)
c) 通知:在切面的某个特定的连接点上执行的动作
i. 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
ii. 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
iii. 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
iv. 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
v. 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
d) 织入:把切面连接到其他的应用程序类型或者对象上,并且创建一个被通知的对象
6、 使用Spring实现AOP
第一种实现方式通过SpringAPI来实现
Log.java—前置通知
public class Log implements MethodBeforeAdvice {
/**
* @param method 被调用的方法对象
* @param args 被调用的方法参数
* @param target 被调用方法的目标对象
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"方法"+args);


}
 
}
AfterLog.java后置通知
public class AfterLog implements AfterReturningAdvice{
/**
  * 目标方法执行后的通知
* returnValue --返回值
* method 被调用的方法对象
* args 被调用的方法对象的参数
* target 被调用的方法对象的目标对象
*/
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行,返回值是"+returnValue);
}
}
目标类:UserServiceImpl.java接口自己看
public class UserServiceImpl implements UserSerive {


@Override
public void add() {
System.out.println("执行add方法");
}


@Override
public void delete() {
System.out.println("执行delete方法");
}


@Override
public void update() {
System.out.println("执行update方法");
}


@Override
public void seva() {
System.out.println("执行seva方法");
}


}


配置文件:
<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.xsd 
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="userService" class="Service.impl.UserServiceImpl"></bean>
  <bean id="log" class="Log.Log"></bean>
  <bean id="afterlog" class="cn.AfterLog" /> 
  <aop:config>
  <!-- aop:pointcut 切入点 
  expression="execution(* Service.impl.*.*(..))"
  第一个*号是所有返回值,第二个为impl下的所有类,第三个为所有类的所有方法
  参数列表的两点代表所有参数
  -->
  <aop:pointcut expression="execution(* Service.impl.*.*(..))" 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 cx = new ClassPathXmlApplicationContext("bean.xml");
UserSerive userSerive = (UserSerive) cx.getBean("userService");
userSerive.add();
}
}


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


自定义类实现AOP
通知类
public class Log  {
public void before() {
System.out.println("方法执行前");
}
public void after() {
System.out.println("方法执行后");

}
配置文件
<bean id="userService" class="Service.impl.UserServiceImpl"></bean>
  <bean id="log" class="Log.Log"></bean> 
  <aop:config>
  <!-- aop:pointcut 切入点 
  expression="execution(* Service.impl.*.*(..))"
  第一个*号是所有返回值,第二个为impl下的所有类,第三个为所有类的所有方法
  参数列表的两点代表所有参数
  -->
  <aop:aspect ref="log">
  <aop:pointcut expression="execution(* Service.impl.*.*(..))" id="pointcut"/>
  <!-- 前置通知 -->
  <aop:before method="before" pointcut-ref="pointcut"/>
  <!-- 后置通知 -->
  <aop:after method="after" pointcut-ref="pointcut"/>
  </aop:aspect>
</aop:config>
被通知类
public class UserServiceImpl implements UserSerive {


@Override
public void add() {
System.out.println("执行add方法");
}


@Override
public void delete() {
System.out.println("执行delete方法");
}
}




使用注解实现AOP
配置文件
<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.xsd 
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="userService" class="Service.impl.UserServiceImpl"></bean>
  <bean id="log" class="Log.Log"></bean> 
  <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        </beans>
测试类
public class Test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("bean.xml");
UserSerive userSerive = (UserSerive) cx.getBean("userService");
userSerive.add();
}
}


通知(注解)类
@Aspect//定义切面
public class Log  {
@Before("execution(* Service.impl.*.*(..))")
public void before() {

System.out.println("方法执行前");
}
@After("execution(* Service.impl.*.*(..))")
public void after() {
System.out.println("方法执行后");
}  
@Around("execution(* Service.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;
}
}
目标类
public class UserServiceImpl implements UserSerive {


@Override
public void add() {
System.out.println("执行add方法");
}


@Override
public void delete() {
System.out.println("执行delete方法");
}


@Override
public void update() {
System.out.println("执行update方法");
}


@Override
public void seva() {
System.out.println("执行seva方法");
}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值