Spring

一.反向控制【Inversion of control】/依赖注入【Dependency Injection】

实现依赖抽象,类依赖接口,接口的实现通过bean注入。

注入

可以对一个对象注入字符串、map,另一个对象等信息。

https://blog.csdn.net/a909301740/article/details/78379720

1.接口注入

public class ClassA {
private InterfaceB clzB;
public Object doSomething(InterfaceB b) {
clzB = b;
return clzB.doIt();
}
}

2.构造器注入

public class DIByConstructor {

private final DataSourcedataSource;
public DIByConstructor(DataSource ds) {
this.dataSource = ds;
}

 

public class Role {
    private int id;
    private String roleName;
    private String note;     
    public Role(){}    
    public Role(int id,String roleName, String note)
    {

      super();
        this.id = id;
        this.roleName = roleName;
        this.note = note;
    }
}

<bean id="Role" class="com.xiaojiang.Spring.Role">

<constructor-arg value="1" type="int"></constructor-arg>

<constructor-arg value="小江" type="java.lang.String"></constructor-arg>

<constructor-arg value="有点丑" type="java.lang.String"></constructor-arg>

</bean>

3.set注入

public class ClassA {
private InterfaceB clzB;
public void setClzB(InterfaceB clzB) {
this. clzB = clzB; }
}

<bean id="Role" class="com.xiaojiang.Spring.Role">

<property name="id" value="1"><property>

<property name="roleName" value="小江"><property>

<property name="note" value="测试"><property>

</bean> 

set和构造器注入使用比较多。

 

 

 

主要配置和注解

<bean   class="bean的完全限定名"
        name/id="bean在容器内的唯一名称"
        
        scope="bean的生命周期"       
        #https://www.cnblogs.com/jianyungsun/p/6839612.html
        #singleton[default] /prototype/request[每一次http请求产生一个新的bean]/session
        
        lazy-init="是否为延迟加载"
        #https://blog.csdn.net/fhx007/article/details/7016704
        #lazy-init 设置只对scop属性为singleton的bean起作用
        
        init-method="bean的setter被调用之后调用该方法进行初始化"
        destroy-method="容器在销毁该Bean后的调用的方法"
        #https://www.cnblogs.com/soundcode/p/6367412.html
        
        abstract="是否为抽象Bean,spring对于抽象bean不产生实例,主要用于继承"
        parent="父Bean的名称,会继承父Bean的属性,与Java的Class无任何关系"
        #https://blog.csdn.net/u010002184/article/details/80628657
        
        factory-method="工厂方法的名字"
        factory-bean="工厂Bean的名字"
        #https://www.cnblogs.com/vickylinj/p/9474597.html
        #实例化工厂类和方法,包括静态和非静态方法
        
        depends-on ="依赖Bean的名字,保证初始化顺序。”   
        #http://zhaohe162.blog.163.com/blog/static/3821679720111171219156/
        #管理依赖关系不明显或没哟直接依赖关系的对象,控制初始化顺序,
        
        autowire="byType" dependency-check="simple/object/all/none"
        #https://www.cnblogs.com/sishang/p/6583057.html
        #自动装配,不显示制定注入的字段。配合使用做检查[基本类型、对象、所有类型、不检查]

        #byType byName property属性设置方法同类型的bean或者和set方法同名的bean。

        #eg.  setDogId(Dog dog)
        > 
       

        <!-- Constructor-arg给属性赋值写法一 -->
        <constructor-arg type="int" value="10"/>
        <!-- Constructor-arg给属性赋值写法二 -->
        <constructor-arg name="age" value="10"/>
        <!-- Constructor-arg给属性赋值写法三 -->
        <constructor-arg index="0" value="10"/>

        <!-- Properties给属性赋值写法一 -->
        <property name="bean1">
             <ref bean="另外一个bean的id"/>
        </property>
        <!-- Properties给属性赋值写法二 -->
        <property name="bean1" ref="另外一个bean的id"/>
        <!-- Properties给属性赋值写法三 -->
        <property name="age" value="10"/>
                
        集合注入方式
        #https://www.cnblogs.com/lihuibin/p/7928893.html
        
</bean>

 

管理bean的方式

ApplicationContext和BeanFactory使用较多,ApplicationContext在BeanFactory基础上,增加了国际化支持,资源访问,时间传递等功能。

1.国际化支持:

https://blog.csdn.net/caomiao2006/article/details/51872442

 

https://www.cnblogs.com/tenWood/p/7535502.html

 

---todo

 

4AOP

4.1 代理

静态代理,动态代理 :接口代理【jdk代理】,cglib代理

静态AOP  :AspectJ

动态AOP:Spring aop

静态AOP编译阶段生成class,性能较好些。

 

具体使用可参考:

  http://www.cnblogs.com/cenyu/p/6289209.html#autoid-1-1-0

  https://www.cnblogs.com/xiaofugua/articles/7251061.html

 

 静态代理,动态代理(接口代理/cglib代理) 使用:https://www.jb51.net/article/110345.htm

 代理原理:http://www.360doc.com/content/14/0801/14/1073512_398598312.shtml

 动态代理调用原理:http://blog.csdn.net/wang_1997/article/details/52450549

反射打印:http://blog.csdn.net/rokii/article/details/4046098

接口代理需要实现InvocationHandler接口,cglib代理需要实现MethodIntercept解口

静态代理和接口代理:需要被代理类实现接口。

cglib代理:被代理的类可以是个普通的类,不需要实现接口。

 

 

接口代理:使用reflect包的反射部分,生成一个代理class文件,此class继承proxy并实现了对应的接口,并且在对应方法中调用

代理类【实现InvocationHandler】的invoke方法。

在运行过程生成代理二进制文件Proxy0,加载class,改class含有对动态代理类(InvocationHandler)的引用,以调用其invoke方法。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import main.designer.proxy.justtest.IUser;

public final class $Proxy0
extends Proxy
implements IUser
{
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

public $Proxy0(InvocationHandler paramInvocationHandler)
throws 
{
super(paramInvocationHandler);
}

public final boolean equals(Object paramObject)
throws 
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int hashCode()
throws 
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final void showSkill()
throws 
{
try
{
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final String toString()
throws 
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m3 = Class.forName("main.designer.proxy.justtest.IUser").getMethod("showSkill", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}

cglib代理:

   

public class CglibProxy implements MethodInterceptor
{
    private static Logger logger = Logger.getLogger(Person.class);

    /**
     * {@inheritDoc}
     */
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2,
            MethodProxy arg3) throws Throwable
    {
        logger.log(Level.INFO, "start to call:" + arg1);
        Object object = arg3.invokeSuper(arg0, arg2);
        logger.log(Level.INFO, "after call:" + arg1);
        return object;
    }
}

 

 

 Enhancer hancEnhancer = new Enhancer();
        CglibProxy proxy = new CglibProxy();
        hancEnhancer.setSuperclass(Person.class);
        hancEnhancer.setCallback(proxy);
        Person p = (Person) hancEnhancer.create();
        p.eat("apple");

CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理

4.2spring配置aop

使用ProxyFactoryBean配置
<!-- 1.自动代理 -->
 <!-- 制定哪些类和方法需要引入通知 -->
<!--  <bean id ="operaImple" class="com.spring.demo.conf.aop.business.InvOperationImpl" />
 <bean id ="operaNormal" class="com.spring.demo.conf.aop.business.InvOperationNormal" />
 <bean id="timeHanderAdvice" class="com.spring.demo.conf.aop.TimeHandler"/> 
<bean id="timeHanderAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
   <property name="advice" ref="timeHanderAdvice"/>
   <property name="patterns" value=".*query.*"/>
</bean>  
 <bean id ="autoProxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />    -->

<!-- 2.ProxyFactoryBean接口代理 -->
<!--2.测试使用 timeProxy获取bean,调用方法会织入特定方法,interceptorNames如果为 timeHanderAdvice,则所有方法都会打印日志-->
<!--   <bean id ="operaImple" class="com.spring.demo.conf.aop.business.InvOperationImpl" />
 <bean id ="operaNormal" class="com.spring.demo.conf.aop.business.InvOperationNormal" />
 <bean id="timeHanderAdvice" class="com.spring.demo.conf.aop.TimeHandler"/>  
 <bean id="timeHanderAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
   <property name="advice" ref="timeHanderAdvice"/>
   <property name="patterns" value=".*query.*"/>
</bean> 
 <bean id="timeProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="operaImple"/>
    <property name="proxyInterfaces" value="com.spring.demo.conf.aop.business.InvOperationInterface"/>
    <property name="interceptorNames" value="timeHanderAdvisor"/>  
 </bean>  -->
 
 <!-- 3.ProxyFactoryBean cglib代理 -->
<!--  <bean id ="operaImple" class="com.spring.demo.conf.aop.business.InvOperationImpl" />
 <bean id ="operaNormal" class="com.spring.demo.conf.aop.business.InvOperationNormal" />
 <bean id="timeHanderAdvice" class="com.spring.demo.conf.aop.TimeHandler"/> 
<bean id="timecglibProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="operaNormal"/>
    <property name="interceptorNames" value="timeHanderAdvice"/>  
 </bean>   -->
 

使用aspect
 <!-- 4.aspect -->
<bean id ="operaImple" class="com.spring.demo.conf.aop.business.InvOperationImpl" />
<bean id ="operaNormal" class="com.spring.demo.conf.aop.business.InvOperationNormal" />
<bean id="timeHanderAdvice" class="com.spring.demo.conf.aop.TimeHandler"/>
<bean id="myaspect" class="com.spring.demo.conf.aop.MyAspect"/>
 

 

aspect:切面 

pointcut:切点

 <aop:config>
    <aop:pointcut expression="execution(public * *(..))" id="mypointcut"/>
    <aop:aspect ref="myaspect">
      <aop:around method="aroundLog" pointcut-ref="mypointcut"/>
      <aop:before method="beforeLog" pointcut-ref="mypointcut"/>  
    </aop:aspect>
 </aop:config> 
 

 

 

 

 

 

 

 

 

1.spring 的国际化
2.事件和监听


3.实现ApplicationContextWare(BeanFactoryAware)接口,bean会设置容器变量

BeanFactory和ApplicationContext
前者不会预先初始化bean,使用到再初始化,ApplicationContext会预先初始化容器中所有singleton bean。

bean输入方式
1.指定bean的class,调用构造器创建bean
<bean id ="manbean" class="com.test.man">
2.调用静态工厂方法创建bean
<bean id ="manbean" class="com.test.factory.Manfactory" factory-method="getBeing">
<constructor-arg value="dog"/>
</>
3.调用实例工厂方法创建bean
<bean id="personFactory" class="com.test.PersonFactory">
<bean id ="manbean" factory-bean="personFactory" factory-method="getPerson">
<constructor-arg value="dog"/>
</>
抽象bean和子bean 抽象bean配置abstract属性,子bean配置parent属性,子bean继承父bean的属性方法,和java继承不同可以是不同类型。


如果一个singleton的bean依赖一个prototype范围的bean,需要配置lookup-method属性,否则注入的都是一个单例。
#Chinese 定义为抽象类,getDog定义为抽象方法,spring会使用代理自动实现返回gunDog的实例。
<bean id="chinese" class="com.app.immple.Chinese">
 <lookup-method name="getDog" bean="gunDog">
</bean>
<bean id="gunDog" class="com.app.imple.GunDog" scope="prototype"/>

注解


@Component("itemDao")
@Lazy(true)
@DependsOn({"steelAxe","abc"})

set方法,注入
@Resource(name="stongAxe") 
@Autowired  --type方式注入

@Autowired
@Qualifier("stongAxe")


@PostConstruct
init-method

@PreDestroy
destroy-methon

aspectj spring aop

spring aop只能针对方法
aspectj 还能针对属性赋值

 

 

 

spring整合事务,hibernate。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值