Spring

1.spring:是一款开源的轻量级DI/IOC/AOP的框架容器
(1)开源的:Spring的源代码是公开免费的
(2)轻量级:容易上手
(3)DI/IOC:把创建对象的权力交给Spring管理控制了
注意:Spring管理的对象叫bean
DI:依赖注入
IOC:控制反转
AOP:面向切面编程 好处:解耦

(4)容器:装东西用的,bean对象的
(5)框架:集合多个jar包的工具

spring的优点:
1.解耦 :高内聚,低耦合
2.致力于J2EE应用的各层的解决方案
2.1.Spring可以渗透java任意一层:controller.service.dao
3.方便集成各种优秀的框架
3.1.世界上基本所有的框架都和Spring进行了无缝集成

Spring两大核心:
1.DI/IOC:把创建对象的权利交给spring
2.AOP:将共同的业务抽取出来作用到目标上去

创建对象

public class Mybean(){}

ApplicationContext.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

	      <!--
	       id是给类取得别名,必须独一无二
	       class是将指定的类交给spring管理,需全限定名,
	       	Spring底层基于反射实现的,调用无参数的构造方法     
	       -->  
	     <bean id="mybean" class="cn.itsources_01Hello.mybean"></bean>   
	      </beans>

	public class mybeanTest extends TestCase {
		public void test(){
		//获取spring的核心配置文件
		Resource resource=new ClassPathResource("applicationContext.xml");
		//创建bean工厂
		BeanFactory beanFactory=new XmlBeanFactory(resource);
		//获取指定的bean对象
		Mybean mybean=(Mybean)beanFactory.getBean("mybean");
		
	}
	
	public void test2(){
	//创建ApplicationContext对象
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
	//获取指定的bean对象
		Mybean mybean=(Mybean)applicationContext.getBean("mybean");
	}
	}

BeanFactory和ApplicationContext的区别

1.ApplicationContext是BeanFactory的子类,有更多的功能和方法(前者支持邮件发送,
后者不支持)
2.在创建ApplicationContext的时候,我们就会去加载配置文件和创建对象
而BeanFactory是在他使用的那一刻才会去加载文件和创建对象

创建对象的三种方式

public void test3(){
		//创建ApplicationContext对象
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		//第一种获取bean对象方式
		Mybean mybean=(Mybean)applicationContext.getBean("mybean");
		//第二种获取bean对象方式
		Mybean mybean=(Mybean)applicationContext.getBean(Mybean.class);
		//第三种获取bean对象方式
		Mybean mybean=(Mybean) applicationContext.getBean("mybean", Mybean.class);
	}

di/ioc:同一个东西,只是看的角度不一样
IOC :控制反转,把控制对象和销毁对象的权力交给spring管理
DI:依赖注入 :给spring对象中属性赋值

 <!-- 
     	property:属性
     	name:属性名
     	value:普通类型设置值
     	ref:只用于对象的引用
      -->
<bean id="mine" class="cn.itsources_02ioc_di.MineBean">
 <property name="name" value="张三"></property>
 <property name="otherbean" ref="other"></property>
 </bean>

属性或对象需要有set方法,否则报错

@Component 不知道当年类属于哪一层就打此注解
@Repository 此注解打在持久层
@Service 此注解打在业务层
@Controller 此注解打在控制层

@Component
public class MyBean {
/**

  • @Autowired 当此字段加了@Autowired之后,他会在当前Spring容器中,查看是否

    有OtherBean对象(先根据类型匹配,类型匹配不上,就根据名字匹配)

    如果匹配上了,就会把Spring管理的OtherBean对象注入到此字段上,如果没有匹配上,则报错

    • */
      @Autowired
      @Resource
      private OtherBean otherbean;
/**@Autowired与@Resource的相同点:都是用来注入字段的
 * 
 * @Autowired与@Resource的区别:
 * 				1.@Autowired是Spring提供的注解,而@Resource是sun公司提供的注解
 * 				2.@Autowired注入是先根据类型注入,然后根据名字注入,
 * 					  而@Resource是先根据名字注入,然后根据类型注入.
 * 				3.以后我们都推荐使用@Autowired,因为他和Spring进行无缝集成
 */

}

spring提供的测试

@RunWith(SpringJUnit4ClassRunner.class)//使用Spring提供的测试工具
@ContextConfiguration("classpath:applicationContext.xml")//在指定位置加载spring的核心配置文件
//@ContextConfiguration  它会自动去加载当前包下面的配置文件,但是这个配置文件的名字必须是 当前类名-Context.xml
public class SpringTest {
@Autowired
private Mybean mybean;
@Test
public void test(){
	System.out.println(mybean.getClass());
}
}

注解注入完整代码

 MyBean中:

@Component
public class Mybean {}

   SpringTest中
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
@Autowired
private Mybean mybean;

@Test
public void test1() {
	System.out.println(mybean);
}
}

  SpringTest-Context.xml中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
    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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        

  <!-- context:component-scan :组件扫描器,只要扫描到
    @Component @Repository @Service @Controller 就创建对象
    @Autowired 自动注入
     base-package  :定义扫描包的位置 
     -->
    <context:component-scan base-package="itsources_05du_ioc_ann"></context:component-scan>
      </beans>

Spring的细节_作用域的设置

注:spring注入默认是单例,即 private Mybean mybean1;
private Mybean mybean2;
syso(mybean1+mybean2);输出的是同一个对象

scope:默认不写,值就是singleton(控制目标创建的类是单例的)
prototype :创建多例对象

Spring的细节_懒加载

public class lazy {
public lazy(){
		System.out.println("被创建了");
	}}
	
	
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
	@Autowired
	private lazy lazy;  //如果不使用懒加载,则不需要此注入,运行test1也会输出被创建了
							而懒加载则需要注入此lazy对象,才能输出
@Test
public void test1(){	
}
}

在xml中
  <!--   需要加载一个配置项,lazy_init  true就是为懒加载 -->
      <bean id="lazy" class="itsources_07lazy.lazy" lazy-init="true"></bean>
        </beans>
或者在文件头中写default-lazy-init="true",则全局懒加载 若都写了,以局部为准

Spring的细节_生命周期方法
单例对象生命周期很长,一直到tomcat关闭才销毁
多例对象中,SPring只负责创建对象,他不会去执行销毁方法,他的对象是由垃圾回收器不定时回收


Spring使用方式
在单例和多例之间切换非常简单 -scope=“singleton/property”
对junit4有集成
从企业的角度:
Spring通常用来整合其他框架

注入
@Autowirde和@Resources
注入:将Spring容器中已存在的对象赋值给当前对象字段

要求:容器中必须有该类类型或子类型的对象

什么时候用注解?什么时候用xml方式?

​ 能用注解的都用注解,别人写好的类不能用注解(api)

哪些类需要交给Spring管理,哪些不需要?
三层对象,其他框架的核心类交给Spring管理
实体对象,集合对象等简单对象不需要交给Spring管理

如果配置文件不在resources下面

<build>
        <!--指定有效的资源文件路径-->
        <resources>
            <resource>
                <!--只要是src/main/java路径下的资源文件都生效-->
                <directory>src/main/java</directory>
                <includes>
                    <!--**代表多级目录-->
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

创建bean的四种方式

 <!--第一种,通过无参构造创建-->
    <bean id="bean1" class="cn.itsource.creatBean._01bean.MyBean"></bean>

    <!--第二种方式,通过静态方法创建-->
    <bean id="Car1" class="cn.itsource.creatBean._02bean.CarFactory" factory-method="getCar1"></bean>

    <!--第三种方式,通过实例方法创建-->
    <bean id="factory" class="cn.itsource.creatBean._02bean.CarFactory"></bean>
    <bean id="car2" factory-bean="factory" factory-method="getCar2"></bean>
    
     <!--第四种,通过FactoryBean创建-->
    <bean id="SqlSessionfactory" class="cn.itsource.creatBean._03bean.SqlSessionFactoryBean"></bean>

通过第二种第三种创建时

public class CarFactory {
    public static Car getCar1(){
        return new Car();
    }
    public Car getCar2(){
        return new Car();
    }
}

第四种,通过实现FactoryBean接口创建

package cn.itsource.creatBean._03bean;

import org.springframework.beans.factory.FactoryBean;

//只要实现了Spring的FactoryBean接口,Spring就会将getObjectType返回的对象进行管理
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>{
    //将返回的对象交给Spring管理
    @Override
    public SqlSessionFactory getObject() throws Exception {
        return new SqlSessionFactory();
    }
    //指定类型
    @Override
    public Class<?> getObjectType() {
        return SqlSessionFactory.class;
    }
    //指定创建单例/原型(多例)
    @Override
    public boolean isSingleton() {
        return true;
    }
}

注入方式

  <!--bean属性注入:setter注入  常用-->
    <bean id="youbean1" class="cn.itsource.di.YouBean">
        <property name="age" value="20"></property>
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>
<!--构造器注入   public YouBean(Integer age, Integer id, String name) {-->
    <bean id="youbean2" class="cn.itsource.di.YouBean">
        <constructor-arg name="age" value="20"></constructor-arg>
        <constructor-arg name="id" value="2"></constructor-arg>
        <constructor-arg name="name" value="jack"></constructor-arg>
    </bean>
<!--构造器注入方式2 类型注入   public YouBean(Integer age, Integer id, String name) {-->
    <bean id="youbean3" class="cn.itsource.di.YouBean">
        <constructor-arg type="java.lang.Integer" value="20"></constructor-arg>
        <constructor-arg type="java.lang.Integer" value="3"></constructor-arg>
        <constructor-arg type="java.lang.String" value="波比"></constructor-arg>
    </bean>
<!--方式3 索引注入   public YouBean(Integer age, Integer id, String name) {-->
    <bean id="youbean4" class="cn.itsource.di.YouBean">
        <constructor-arg index="0" value="20"></constructor-arg>
        <constructor-arg index="1" value="4"></constructor-arg>
        <constructor-arg index="2" value="阿骨打"></constructor-arg>
    </bean>
    <!--方式4 顺序注入   public YouBean(Integer age, Integer id, String name) {-->
    <bean id="youbean5" class="cn.itsource.di.YouBean">
        <constructor-arg value="20"></constructor-arg>
        <constructor-arg value="5"></constructor-arg>
        <constructor-arg value="王麻子"></constructor-arg>
    </bean>

注入对象,简单对象,集合对象,数组对象,集合,资源文件

<bean id="otherbean" class="cn.itsource.di02.OtherBean"></bean>
    <bean id="bean" class="cn.itsource.di02.bean">
        <property name="name" value="张三"></property>
        <property name="id" value="15"></property>
        <property name="age" value="5"></property>
        <!--注入外部bean 可以多次调用-->
       <!-- <property name="otherBean" ref="otherbean"></property>-->
        <!--注入内部bean-->
        <property name="otherBean">
            <bean class="cn.itsource.di02.OtherBean"></bean>
        </property>
        <property name="list">
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>张三</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>张三</value>
                <value>李四</value>
                <value>张三</value>
            </set>
        </property>
        <property name="pros">
            <props>
                <prop key="username">张三</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
        <property name="otherBeanSet">
            <set>
                <!--不同的对象-->
               <!-- <bean class="cn.itsource.di02.OtherBean"></bean>
                <bean class="cn.itsource.di02.OtherBean"></bean>-->
                <!--同一个对象-->
                <ref bean="otherbean"></ref>
                <ref bean="otherbean"></ref>
            </set>
        </property>
    </bean>

代理:分为动态代理和静态代理
静态代理:执行之前先有代理,一个代理类只为一个类服务,基本不用
动态代理:执行的时候使用反射机制动态自动生成代理类,穿什么类就自动生成代理类[泛型+反射],常用

面试题:throwable和Exception的区别

​ Object
​ 丨
​ ThrowAble
​ 丨
​ Error Exception

​ 丨
​ RunTimeException 非RunTimeException

实现aop
1.引入事务依赖和aop依赖

  <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.2.5.RELEASE</version>
  </dependency>

2.配置aop配置

xml头文件中加入 xmlns:aop="http://www.springframework.org/schema/aop"
 http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd
 <bean id="txManager" class="cn.itsource.aopxml.service.TxManager"></bean>
    <aop:config>
<!--目标 service-->
        <!--aop:pointcut 配置切入点即目标
            expression 表达式
            execution() 方法限定表达式
            * cn.itsource.aopxml.service.impl.UserServiceImpl.*(..)) 作用到UserServiceImpl类所有的,任意参数的,任意返回值的方法
        -->
        <aop:pointcut id="txPointuct" expression="execution(* cn.itsource.aopxml.service.impl.UserServiceImpl.*(..))"/>
<!--切面 TxManager-->
        <aop:aspect ref="txManager">
            <!--将txManager.begin方法作用在txPointuct,即作用到UserServiceImpl类所有的方法之前-->
          <!--  <aop:before method="begin" pointcut-ref="txPointuct"></aop:before> 前置通知
            <aop:after-returning method="commit" pointcut-ref="txPointuct"></aop:after-returning>后置通知
            <aop:after-throwing method="rollback" pointcut-ref="txPointuct"></aop:after-throwing>异常通知
            <aop:after method="close" pointcut-ref="txPointuct"></aop:after>--><!--最终通知-->
           
        </aop:aspect>
    </aop:config>
    
    但是这种方式会遇到执行顺序的问题,而且重复代码较多

所以使用环绕方法,在TxManager中加一个方法

  public void around(ProceedingJoinPoint joinPoint){
        try{
            begin();
            joinPoint.proceed();//执行目标方法,自动调用Service中的方法
            commit();
        }catch(Throwable e){
            e.printStackTrace();
            rollback();
        }finally{
            close();
        }
    }
 随后在xml中写
 <aop:pointcut id="txPointuct" expression=
 "execution(* cn.itsource.aopxml.service.impl.UserServiceImpl.*(..))"/>
 <aop:aspect ref="txManager">
<aop:around method="around" pointcut-ref="txPointuct"></aop:around><!--环绕通知-->
        </aop:aspect>
    </aop:config>

在这里插入图片描述

使用注解方式
1.配置文件开启扫描和aop注解支持

<context:component-scan base-package="cn.itsource.aopannotation"></context:component-scan>
    <!--支持aop注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

随后在TxManager中方法注解

@Component
@Aspect  //指定当前类是一个切面类
public class TxManager {
 @Around("execution(* cn.itsource.aopannotation.service.impl.DeptServiceImpl.*(..))")
    public void around(ProceedingJoinPoint joinPoint){
        try{
            begin();
            joinPoint.proceed();//执行目标方法,自动调用Service中的方法
            commit();
        }catch(Throwable e){
            e.printStackTrace();
            rollback();
        }finally{
            close();
        }
    }
}

总结:xml方式用的比较多,因为需要用的切面类一般是别人写好的,没办法在上面加@Aspect

AOP使用场景:事务管理,日志管理,权限验证,性能追踪,异常处理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值