spring基础用法

applicationContext基础配置

IOC配置

1、 基本配置
<?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-4.3.xsd">
</beans> 
2、 给bean起别名
<!-- name属性用来给bean命名,原来名和name里的值都可以使用,并且可以用"," ";" " "分割 -->
<bean id="helloT" class="com.tcc.entity.HelloT" name="hello2,h1;h2 h3">
    <!-- <constructor-arg name="stringT" value="3.1415926" /> -->
    <property name="stringT" value="stringT"/>
</bean>
<alias name="" alias=""/>
3、 导入其他xml文件
<!-- 多个人开发时,用于引入别人写的xml配置文件 -->
<import resource="beans.xml"/>把类放入bean里
4、 把类放入bean里
<bean id="..." class="com.xxx.xxx"></bean>
5、 bean标签中属性
  • autowire自动注入:autowire=“byName|byType|no”
    模式说明
    no不使用自动装配。必须通过ref元素指定依赖,这是默认设置。由于显式指定协作者可以使配置更灵活、更清晰,因此对于较大的部署配置,推荐采用该设置。
    byName根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配
    byType如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则属性不会被设置。
  • scope Bean作用域:scope=“singleton|prototype|request|session|application|websocket”

    在这里插入图片描述

  • name命名:name=“h1,h2;h3 h4”
    • name属性用来给bean命名,原来名和name里的值都可以使用,并且可以用 " , or ; or 空格 "分割
    <bean id="hello" class="com.tcc.entity.Hello" name="h1,h2;h3 h4"/>
    
6、实体类注入值(set注入,构造器注入)
6.1、set注入值(实体类中要有:set方法)
  • set注入用:
<property name="string1" value="String1"/>
6.2、构造器注入值三种方法(实体类中要有:有参构造方法)
  • 通过下标注入:

    <!-- 通过下标赋值 -->
    <constructor-arg index="0" value="123456" />
    
  • 通过类型注入: 如果属性类型相同则不能使用 不建议

    <!-- 通过类型赋值,如果属性类型相同则不能使用  不建议 -->
    <constructor-arg type="java.lang.String" value="123456" />
    
  • 通过变量名注入:

    <!-- 通过变量名注入,最常用 -->
    <constructor-arg name="string1" value="3.1415" />
    
7、特殊类型注入值
  • 引用类型注入:

    <bean id="dog" class="com.tcc.entity.Dog"/>
    <bean id="cat" class="com.tcc.entity.Cat"/>
      	
    <bean id="people" class="com.tcc.entity.People">
      <property name="dog" ref="dog"/>
      <property name="cat" ref="cat"/>
    </bean>
    
  • 数组:

    <property name="shuZu1">
        <list>
          <value>1</value>
          <value>2</value>
          <value>3</value>
        </list>
    </property>
    
  • 集合:

    <property name="list1">
        <array>
          <value>2</value>
          <value>3</value>
          <value>4</value>
        </array>
    </property>
    
  • Map:

    <property name="map1">
        <map>
          <entry key="姓名" value="小黑"/>
          <entry key="爱好" value=""/>
        </map>
    </property>
    
  • Set:

    <property name="set1">
    	<set>
    		<value>set1</value>
    	</set>
    </property>
    
  • Null:

    <property name="stringNull">
      <null/>
    </property>
    
  • Properties:

    <property name="properties1">
      <props>
        <prop key="driver">com.mysql.jdbc.Driver</prop>
        <prop key="url">123123</prop>
        <prop key="username">root</prop>
        <prop key="password">admin</prop>
      </props>
    </property>
    
8、P命名空间
  • P命名空间(set注入):在bean标签里面加上 p:string1=“string1”

  • xml里面添加配置:xmlns:p=“http://www.springframework.org/schema/p”

    <bean id="address" class="com.tcc.entity.Address" p:address="address1"/>
    
9、C命名空间
  • C命名空间(构造器注入):在bean标签里面加上 c:string1=“string1”

  • 注意!:c是通过构造器注入的,所以该对象的所有属性要一次性都用C命名赋值以后才能构造成功否则有参构造将会缺少其他参数报错!

  • xml里面添加配置:xmlns:c=“http://www.springframework.org/schema/c”

    <bean id="address" class="com.tcc.entity.Address" c:address="address1"/>
    

注解

  • 环境配置
    • 先导入spring-aop-4.3.7.RELEASE.jar包

      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              https://www.springframework.org/schema/context/spring-context.xsd">
              
              <!-- 下面这个是扫描这个包里面的所有注解 -->
              <context:component-scan base-package="com.tcc.entity"/>
               <context:annotation-config/>
         	
      </beans>
      
常用注解
1、@Autowired:用于属性的自动注入。
  • 是【autowire=“byName”】和【autowire=“byType”】的结合体

  • 他会先根据"byType"进行查询,如果没有匹配成功则通过"byName"查询。

    • @Autowired既可放在字段前,也可放在setter方法前

      private String name;
      	@Autowired
      	private Dog dog;
      @Autowired
      	private Cat cat;
      
2、 @Qualifier(value=“dog1”):和@Autowired一起使用
  • 如果byName和byType都不匹配,则通过value的值来寻找id匹配的值。

    private String name;
      	@Autowired
      	@Qualifier("dog1")
      	private Dog dog;
      	@Autowired
      	private Cat cat;
    
    总结:使用 @Autowired注解自动装配依赖的过程如下:
      1.首先根据属性的类型(或方法、构造方法参数的类型)在Spring 应用容器中查找类型匹配的bean 
      2.如果没有类型匹配的bean,抛出BeanCreationException;如果只有一个,则注入依赖,完成自动装		配;如果不只一个,则继续执行步骤3; 
      3.如果通过 @Qualifier指定了bean 名称,则从所有符合类型的bean中返回指定的bean,完成自动装			配;如果没有通过 @Qualifier制定bean 名称,则通过反射技术获取当前属性的名称作为bean 名称		返回指定的bean,完成自动装配。
    
3、 @Resource:@Resource由J2EE提供,作用相当于@Autowired。
  • @Autowired是按byType自动注入,而@Resource默认按 byName自动注入。

  • @Resource有两个属性是比较重要的,分别是name和type

  • @Resource既可放在字段前,也可放在setter方法前

    private String name;
    	/*@Autowired
    	@Qualifier("dog1")*/
    	@Resource(name="dog")
    	private Dog dog;
    	/*@Autowired*/
    	@Resource(type=Cat.class)
    	private Cat cat;
    
4、@Component:将类放入bean中
  • bean名称默认为将第一个字母转换为小写的类名。

  • bean名称默认为将第一个字母转换为小写的类名。

  • @Component注解唯一的一个可选参数是value,用于指定bean的名称(即id值,所以必须是唯一的)

     @Component(value="computer") 
     public class Computer {}  
     
     //注解中的value属性可以省略,可以简写为:
     @Component("computer")
     public class Computer {} 
    
     Spring还提供了更加细化的用于定义bean的注解形式:
     	1.@Repository、@Service、@Controller,
     	2.它们分别对应数据访问层bean,业务层bean,和视图层bean。
     	3.目前版本中,这些注解与@Component的语义是一样的,完全通用,在Spring以后的版本中可能会给它们追		加更多的语义。
     	4.所以,我们推荐使用@Repository、@Service、@Controller来替代@Component。
    
    
5、@Scope:@Scope用于定义bean的作用域。
  • singleton表示在每个Spring IoC容器中一个bean定义对应一个对象实例,即Spring默认使用单例模式获取实例。

  • prototype表示一个bean定义对应多个对象实例,即非单例模式,我们常称作多例。

    • 默认情况下,Spring bean 的作用域为 singleton。

      @Component 
      @Scope("prototype")
      public class Computer {} 
      
利用configuration.java来充当xml文件
  1. @Configuration:表示这个类是配置类

  2. @Bean:将下面这个类放到bean里面

@org.springframework.context.annotation.Configuration
public class Configuration {
	
	@Bean
	public Cat cat(){
		return new Cat();
	}
	@Bean
	public Dog dog(){
		return new Dog();
	}
	@Bean
	public People people(){
		return new People();
	}
  1. 测试:AnnotationConfigApplicationContext(Configuration.class);

    public class MyTest {
    	public static void main(String[] args){
    		ApplicationContext context=new AnnotationConfigApplicationContext(Configuration.class);
    		People p = context.getBean(People.class);
    		p.getDog().jiao();
    		p.getCat().jiao();
    	}
    
    }
    

动态代理(了解)

创建接口和impl

package com.tcc.servlet;

public interface UserServlet {
	public void add();
	public void delete();
	public void update();
	public void selete();

}

package com.tcc.servlet;

public class UserServletImpl implements UserServlet{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("添加的方法");
		
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("删除的方法");
		
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新的方法");
		
	}

	@Override
	public void selete() {
		// TODO Auto-generated method stub
		System.out.println("查询的方法");
		
	}

}

创建代理类和实现动态代理的方法(工具类)

package com.tcc.proxy;

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

import com.tcc.entity.User;
import com.tcc.servlet.UserServlet;


//利用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler{
	private Object target;
	

	//调用set方法设置要代理的对象
	public void setTarget(Object target) {
		this.target = target;
	}
	
	//生成得到代理类
	public Object getProxy(){
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
		
	}


	//处理代理实例,并返回结果
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		Object result = method.invoke(target, args);
		logger(method.getName());
		return result;
	}
	
	public void logger(String msg){
		System.out.println("执行了"+msg+"方法");
	}

}

测试:

package com.tcc.test;

import com.tcc.proxy.ProxyInvocationHandler;
import com.tcc.servlet.UserServlet;
import com.tcc.servlet.UserServletImpl;

public class MyTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//真实角色
		UserServlet userServlet = new UserServletImpl();
		//代理角色,不存在
		ProxyInvocationHandler pih = new ProxyInvocationHandler();
		
		//设置要代理的对象
		pih.setTarget(userServlet);
		
		//动态生成代理类
		UserServlet proxy = (UserServlet) pih.getProxy();
		
		proxy.delete();

	}

}

AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个 热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑 的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高 了开发的效率。

AOP 中包含许多新的概念与术语,说明如下: 
1) 切面 (Aspect):切面是系统中抽象出来的的某一个功能模块。 
2) 连接点 (Joinpoint):程序执行过程中某个特定的点,如调用某方法或者处理异常时。在SpringAOP中,连接点总是代表某个方法的执行。 
3) 通知 (Advice):通知是切面的具体实现,是放置“切面代码”的类。 
4) 切入点 (Pointcut):多个连接点组成一个切入点,可以使用切入点表达式来表示。 
5) 目标对象 (Target Object):包含一个连接点的对象,即被拦截的对象。 
6) AOP代理 (AOP Proxy):AOP框架产生的对象,是通知和目标对象的结合体。 
7) 织入 (Weaving):将切入点和通知结合的过程称为织入。

导入jar包

在这里插入图片描述

方式一:使用spring的API接口

1、创建接口和方法

2、创建log包,BeforeLog类实现(MethodBeforeAdvice类)和AfterLog类实现(AfterReturningAdvice类)。

package com.tcc.log;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeLog implements MethodBeforeAdvice{

	@Override
	//method(arg0):	要执行目标的方法
	//args(arg1):	参数
	//target(arg2):	目标对象
	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(target.getClass().getName()+"的"+method.getName()+"方法准备执行");
	}
	

}

package com.tcc.log;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class AfterLog implements AfterReturningAdvice{

	@Override
	//resultValue(arg0):	方法的返回值
	//method(arg1):	要执行目标的方法
	//args(arg2):	参数
	//target(arg3):	目标对象
	public void afterReturning(Object resultValue, Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(target.getClass().getName()+"的"+method.getName()+"方法执行完毕,返回值为:"+resultValue);
	}

}

将接口和log里的两个类添加到beans

在配置文件中添加aop约束

<?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-4.3.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	
	
</beans> 

添加Bean

<bean id="userServce" class="com.tcc.servlet.UserServiceImpl"/>
<bean id="beforeLog" class="com.tcc.log.BeforeLog"/>
<bean id="afterLog" class="com.tcc.log.AfterLog"/>

添加切面(方法一)

<!-- 方式一:使用原生spring API接口 -->
<!-- 配置aop需要导入aop的约束 -->
<aop:config>
  <!-- 切入点:	execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) -->
  <aop:pointcut expression="execution(* com.tcc.servlet.UserServiceImpl.*(..))" id="pointcut"/>

  <!-- 执行环绕增加 -->
  <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
  <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>


</aop:config>

测试:

package com.tcc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tcc.servlet.UserService;

public class MyTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//动态代理代理的是接口
		UserService userService = context.getBean(UserService.class);
		userService.add();

	}

}
方式二:自定义实现AOP

创建com.tcc.diyLog包,创建Diy

package com.tcc.diyLog;

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

}

在applicationContext.xml中写入aop

<!-- 方式二:自定义实现AOP -->
<bean id="diy" class="com.tcc.diyLog.DiyPointCut"/>
<bean id="userServce" class="com.tcc.servlet.UserServiceImpl"/>
<bean id="beforeLog" class="com.tcc.log.BeforeLog"/>
<bean id="afterLog" class="com.tcc.log.AfterLog"/>

<aop:config>
  <!-- 自定义切面:ref要引用的类 -->
  <aop:aspect ref="diy">
    <!-- 切入点 -->
    <aop:pointcut expression="execution(* com.tcc.servlet.UserServiceImpl.*(..))" id="pointcut"/>

    <!-- 通知 method:方法名-->
    <aop:before method="before" pointcut-ref="pointcut"/>
    <aop:after method="after" pointcut-ref="pointcut"/>

  </aop:aspect>

</aop:config>
方式三:注解实现AOP

创建AnnocationPointCut类

1、@Aspect:将当前类定义为切面

2、@Before(“execution(* com.tcc.servlet.UserService.*(…))”):在这个类方法执行前执行下面的方法

3、@After(“execution(* com.tcc.servlet.UserService.*(…))”):在这个类方法执行后执行下面的方法

package com.tcc.diyLog;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//使用注解定义切面
@Aspect
public class AnnocationPointCut {

	@Before("execution(* com.tcc.servlet.UserService.*(..))")
	public void before(){
		System.out.println("===============方法执行前=================");
	}
	
	@After("execution(* com.tcc.servlet.UserService.*(..))")
	public void after(){
		System.out.println("================方法执行后================");
	}
}

优化:

@Pointcut("execution(* com.tcc.servlet.UserService.*(..))")
public void p1(){};
package com.tcc.diyLog;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

//使用注解定义切面
@Aspect
@Component
public class AnnocationPointCut {
	
	@Pointcut("execution(* com.tcc.servlet.UserService.*(..))")
	public void p1(){};
	
	@Before("p1()")
	public void before(){
		System.out.println("===============方法执行前=================");
	}
	
	@After("p1()")
	public void after(){
		System.out.println("================方法执行后================");
	}
	
	//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点:
	@Around("p1()")
	public void around(ProceedingJoinPoint pj) throws Throwable{
		System.out.println("环绕前");
		
		//执行方法   方法上面是前置,方法下面的是后置
		Object proceed = pj.proceed();
		//获得签名
		Signature signature = pj.getSignature();
		System.out.println(signature);
		
		System.out.println("环绕后");
	}
}

或:(不常用)

//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点:
@Around("execution(* com.tcc.servlet.UserService.*(..))")
public void around(ProceedingJoinPoint pj) throws Throwable{
  System.out.println("环绕前");
  
  //执行方法
  Object proceed = pj.proceed();
  //获得签名
  Signature signature = pj.getSignature();
  System.out.println(signature);

  System.out.println("环绕后");
}

结果:

环绕前
===============方法执行前=================
查询了用户
void com.tcc.servlet.UserService.selete()
环绕后
================方法执行后================

applicationContext.xml配置

<!-- 方式三:使用注解 -->
<bean id="annocationPointCut" class="com.tcc.diyLog.AnnocationPointCut"/>
<!-- 开启注解支持 	jdk(默认):proxy-target-class="false"		
cglib:proxy-target-class="true"-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
execution

在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点"

例如定义切入点表达式 execution (* com.sample.service.impl….(…))

execution()是最常用的切点函数,其语法如下所示:

整个表达式可以分为五个部分:

1、execution(): 表达式主体。

2、第一个星号:表示返回类型,*号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。

4、第二个星号:表示类名,*号表示所有的类。

5、*(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

**execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) 除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。**与其直接讲解该方法的使用规则,还不如通过一个个具体的例子进行理解

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值