浅谈Spring

一.Spring的简介(本质是容器)

Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于J2EE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
Spring官方文档

二、对IOC【控制反转】,DI【依赖注入】的理解

IOC(Inversion of Control,控制反转)是Spring实现的核心,IOC实现对应用程序对象的控制反转,控制反转并不是顺序发生变化,而是在应用程序中创建对象角色的反
转,将原本是由应用程序创建对象的任务在IOC容器创建了,这就是IOC控制反转【动态的想客户端提供所需要的其他对象】。
DI,(Dependency injection 依赖注入【被注入对象依赖IoC容器配置依赖对象】),DI常与IOC在Spring中搭配使用,DI在Spring框架中扮演着为IOC容器中创建的对象进行
外部资源注入角色,使得代码的工作量变少,

三·、静态代理与动态代理的理解

静态代理:手动去创建一个代理类,在不改变源码的前提下来对基本业务进行横向扩充,代理模式本质是媒介,真实角色将业务交给代理类来调用,客户端访问只需要通过代理
类来进行访问,但是静态代理模式具有一定的局限性,每承担一个真实角色的业务,就需要创建一个代理类,造成资源的浪费,代码的复用性降低。
动态代理:使用者通过创建一个类来继承InvocationHandler接口,借助于Proxy类得到newProxyInstance(类加载器,被代理的接口,本身的类)获取代理类;接下来是处理结果 invoke方法可以帮我们处理结果,这样我们一个动态代理类获取就已经完成了,客户端就可以通过它来知道相应的业务;动态代理底层是利用JDK反射来实现的。
反射的概念:(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键

四、AOP面向切面编程的感悟

Spring框架中的AOP,是对于在实际的业务需求下,我们在不改变代码的纵向运行的条件下,对业务实现横向扩展,与代理模式不同的是,针对于某个类或者某个包,称之为连接点;我们创建一个类叫做扩展业务类,其就是切面;再进行一个通知操作,作用是将切面中的方法,引入到切点中【这步是在IOC中实现的】;切点中得到切面后是织入连接点上,这样业务的横向发展完成了,同时这个操作也称之为AOP即为面向切面编程,这种思想是重要的!

五.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"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--        import 导入其他配置文件合并为一个总配置文件applicationContext(全名)
        一般用于团队开发,
-->
    <import resource="beans.xml"/>

</beans>

六.DI注入(applicationContext.xml配置文件中进行注入)

1.DI-构造器器注入

<?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">
<!--    使用spring创建对象,在spring中统称Bean
    对象由Spring创建,
    对象属性由Spring设置
  正常情况:类型 变量名=new 类型();
  使用spring:id=变量名(唯一标识符)
            class=new 的对象(bean对象的全限定类名:包名+类名)
            name:取别名,可以同时对一个对象取多个别名
            property:对象属性值得设置
-->
<!--        默认以无参构造器 new的对象-->
    	<bean id="Man" class="com.gec.pojo.Man" name="man">
       	 <property name="name" value="Spring"/>
    	</bean>
<!--       有参构造器 new对象-->
<bean id="user" class="com.gec.pojo.User">
<!--        第一种:下标赋值-->
<!--        <constructor-arg index="0" value="小明"/>-->
<!--        第二种:通过类型创建,若有相同类型的属性不是容易处理,(不建议使用)-->
<!--        <constructor-arg type="java.lang.String" value="小红"/>-->
<!--        第三种:直接通过实体类中参数名来设置-->
    <constructor-arg name="name" value="小花"/>
</bean>
<bean id="usert" class="com.gec.pojo.UserT">

 </bean>
</beans>

2,DI-set方法注入(不同数据的注入方式)

三国演义 水浒传 西游记 红楼梦 吃饭 睡觉 大豆豆 绝地求生 LOL QQ农场 毛毛 男 18
    <bean id="address" class="com.gec.pojo.Address">
            <property name="address" value="狗熊岭"/>
    </bean>

3.测试

//    提供给ApplicationContext构造函数的位置路径是资源字符串,
//    这些资源字符串使容器可以从各种外部资源(例如本地文件系统,Java CLASSPATH等)加载配置元数据
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//    对象都被在spring中被代理理了, 我们使用的时候只需要从Spring容器中取出即可
//使用时取出的是配置文件Bean中设置的id属性值,直接get就ok
//在getBean的时候Man对象属性就已经初始化了
Man man = (Man) context.getBean("man");
System.out.println(man.toString());

七.Bean的作用域

在这里插入图片描述

a.singleton单例模式【Spring默认的机制】

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

代码实现:

<bean id="Man" class="com.gec.pojo.Man" name="man" scope="singleton">
	<property name="name" value="Spring"/>
</bean>

b.prototype原型默认【每次从容器中get时都会产生一个对象】

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

代码实现:

<bean id="Man" class="com.gec.pojo.Man" name="man" scope="prototype">
	<property name="name" value="Spring"/>
</bean>

八、Spring的自动装配

1.自动装配Bean

(1).自动装配是Spring满足bean依赖注入的一种方式
(2)Spring会在上下文中自动寻找,去装配bean的属性

2.隐式的自动装配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"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="cat" class="com.gec.pojo.Cat"/>
<bean id="dog" class="com.gec.pojo.Dog"/>

<!--
    autowire:根据那种要求进行自动装配
    byName:autowire会在上下文中自动寻找与People下set方法后面值对应的bean id【保证bean id 唯一】
<bean id="people" class="com.gec.pojo.People" autowire="byName">
    <property name="name" value="小妹"/>
</bean>
===================================================================		===================
byType:autowire会在上下文中自动寻找与People中封装对象属性相同的bean【保证bean中属性对象的class 唯一】
<bean id="people" class="com.gec.pojo.People" autowire="byType">
    <property name="name" value="小妹"/>
</bean>
-->
<bean id="people" class="com.gec.pojo.People" autowire="byType">
    <property name="name" value="小妹"/>
</bean>
###3.注解实现自动装配 dao层: @Repository组件的意思 代表将改=该类注册到Spring中,装配到bean中 实体类:
@Component【组件】等价于    	
<bean id="user" class="com.gec.pojo.User"/>
@Value【组件】等价于    <property name="name" value="豆豆"/>

service层:
@Service代表将改=该类注册到Spring中,装配到bean中
controller层:
代表将改=该类注册到Spring中,装配到bean中
@Controller
通过注解的方式来实现配置文件的操作:
//@Configuration代表的是一个配置类和Beans.xml相等
// 也会被注册到Spring中因为本质就是@Component
//
@Configuration
//监听这个类中全部的注解
@ComponentScan(“com.gec.pojo”)
//导入其他使用注解操作的bean
@Import(CatConfig.class)

public class Dogconfig {

//    @Bean:注册一个bean代表一个<bean><bean/>标签
//    方法名就是bean id
//      返回值代表bean class
//
@Bean
public  Dog dog(){
    //返回的就是注入对象
    return new Dog();
}

}

在这里插入图片描述

2.静态代理模式

图示:
在这里插入图片描述
静态代理角色分析:
抽象的角色:一般是实现类或者接口中介与房东共同的目的出租房子
客户:等价于租客,是客户,来租房子的
代理角色:代理真是角色,=中介
真实角色:被代理的角色
房东,出租房子 (一般用于去实现接口)
静态代理模式的优缺点:
优点:代理模块用来处理公共业务,方便真实角色去处理自己本身对应的业务,
代理模式实现业务分离,便于管理
缺点:一个真实角色会需要一个代理对象,多个真实角色就会需要多个代理对象,开发效率低!

3.动态代理模式(动态的生成proxy代理类【媒介】)

动态代理和静态代理的角色一样
动态代理是动态生成的
动态代理的实现分为两种:一种是基于接口实现,另外一种是基于类来实现
基于接口实现=========JDK动态代理
基于类实现==========cglib
java字节码实现===javasist

(1).使用的相关类

a.Proxy
InvocationHandler (Java Platform SE 8 )调用处理程序

(2).动态代理对象的生成

a、通过Proxy类中的newProxyInstance方法来生成代理类
该方法中有三个参数:类加载器,代理对象实现的接口,调用处理程序
public Object getProxy(){
//newProxyInstance中第一个(类加载器)和第三个参数是固定(目前) 只需要改变第二个参数即可
//ren.getClass().getInterfaces()=获取被代理的接口
return Proxy.newProxyInstance
        (this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);

}

b、处理代理实例,并返回一个结果; InvocationHandler (Java Platform SE 8 )当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。
该方法中有三个参数:proxy调用该方法的代理实例,method所述方法对应调用代理实例上接口实例的方法的实例
args包含方法调用传递代理实例参数值的对象阵列,或者如果接口方法没有参数传递的为null值,包括原始类型
 //处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	//动态代理的本质就是反射机制实现的
	 Object reuslt = method.invoke(target, args);
	 return reuslt;
}
c、测试
//创建的房东对象即是真实对象
master mas=new master();
//此时还没有创建代理类
ProInvocationHandler pih = new ProInvocationHandler();
//通过调用处理程序来处理真实被代理的对象(角色房东),将真实对象入参到setRen方法中,来处理;
pih.setRen(mas);
//proxy是动态生成的代理对象
//Ren是.代理对象实现的接口
Ren proxy = (Ren) pih.getProxy();
proxy.lease();

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

<!--    注册bean-->
    <bean id="userImpl" class="com.gec.service2.UserServiceImpl2" />
    <bean id="beforlog" class="com.gec.log.BeforLog"/>
    <bean id="afterlog" class="com.gec.log.AfterLog"/>
    方式一:通过SpringAPI接口来实现的AOP
<!--    配置aop-->
<!--&lt;!&ndash;  需要导入aop及aop约束&ndash;&gt;-->
<!--    <aop:config>-->
<!--&lt;!&ndash;-->
<!--            配置切入点;expression:要切入的切点,(执行的位置)-->
<!--            execution(* 插入的具体位置.*【这个类中所有方法】 )-->
<!--            execution(* com.gec.service2.UserServiceImpl2.*(..))-->
<!--&ndash;&gt;-->
<!--        <aop:pointcut id="pointcut" expression="execution(* com.gec.service2.UserServiceImpl2.* (..))"/>-->
<!--&lt;!&ndash;        执行环绕&ndash;&gt;-->
<!--        <aop:advisor advice-ref="beforlog" pointcut-ref="pointcut"/>-->
<!--        <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>-->
<!--    </aop:config>-->

        方法二:通过自定义切面 来实现AOP
<!--    注册自定义的一个类 是横向延伸的一个业务操作类-->
    <bean id="diy" class="com.gec.log.diy"/>
    <aop:config>
<!--        引入切面 -->
        <aop:aspect  ref="diy">
<!--            是要引入切面的切点位置-->
            <aop:pointcut id="pointcut" expression="execution(* com.gec.service2.UserServiceImpl2.* (..))"/>
<!--            通知向切点加入的方法或业务-->
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

方法三:
//方法三利用注解来实现AOP
@Aspect//标记为一个切面
public class Aonntist {
//执行前的注解 切点
@Before(“execution(* com.gec.service2.UserServiceImpl2.* (…))”)
public void before(){
System.out.println(“=============method run before”);
}
//执行后 切点
@After(“execution(* com.gec.service2.UserServiceImpl2.* (…))”)
public void after(){
System.out.println(“=============method end after”);
}
@Around(“execution(* com.gec.service2.UserServiceImpl2.* (…))”)
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println(“环绕前”);
Object proceed = jp.proceed();
System.out.println(proceed);//方法的返回
Signature signature = jp.getSignature();//签名
System.out.println(“执行方法的签名:” +signature);
System.out.println(“环绕后”);
}

事务回顾和Spring式事务

事务:
ACID:原子性,一致性,隔离性,持久性;
分为两种:编程式事务【会改变源码】和spring式事务【通过动态代理来实现】

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
 </bean>
<tx:advice id="transaction" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>
<aop:config>
    <aop:pointcut id="txPointcut" expression="execution(* com.gec.mapper.*.*(..) )"/>
    <aop:advisor advice-ref="transaction" pointcut-ref="txPointcut"/>
</aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值