Spring学习笔记

在配置好需要的文件后就可以进行编程学习了。。
Spring基于XML文件配置Bean的方法:
在IOC容器中配置:

 <beans  ... ...>
 <bean id="helloWorld" class="com.spring.beans.HelloWorld">
 <property name="name" value="spring"></property>     //属性注入
 <property name="sex" value="man"></property>
 <constructor-arg value="spring" ></constructor-arg> //构造器注入
 <constructor-arg value="sex"></constructor-arg>
 <constructor-arg value="spring" index="0"></constructor-arg>  //和上例效果相同
 <constructor-arg value="sex" index="1">
 <constructor-arg value="spring" type="String"></constructor-arg>
 <constructor-arg value="sex" type="String"></constructor-arg>
 </bean>
</beans>

1.创建spring的IOC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2.从IOC容器中获取Bean的实例
HelloWorld helloWorld=(HelloWorld)ctx.getBean(HelloWorld.class); //只能有一个HelloWorld类型的Bean

HelloWorld helloWorld=ctx.getBean("helloWorld");

属性配置细节
1.当要给变量赋值特殊符号时可用<![CDATA["赋值内容"]]>包裹起来。
2.属性值也可以用 value 直接点进行配置
3.可以使用property的 ref 属性建立 bean之间的引用关系。
4.内部 Bean 不能被外部影响,只能内部使用。
5.可以使用 <null/> 标签为某些属性注入 null 值
6.使用级联属性赋值时,必须先初始化后才可以为级联属性赋值,当前 Bean 内必须有 get和set -ref对象的方法。
7.使用<list>标签时,若引用的 Bean 是另一个包里的同名类,则应 import 另一个包的该同名类。
8.使用 util 标签来配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间。
9.使用 P命名空间为 bean 的属性赋值,需要导入p命名空间。相对于传统的方式更加简洁。
格式 : <bean id="person" class="com.spring.beans.Person" p:name="name" p:age="15" ></bean>
10.可以使用 autowire 自动装配,有byName,byType,constructor等方式。
<bean id="person" class="com.spring.beans.autowire.Person"
autowire="byName">
</bean>
11.bean之间的关系:bean 可以继承 (parent)、依赖(depends-on),bean的abstract属性为true,这样的bean不能被IOC容器实例化,只用来被继承配置
不会继承 bean 的所有属性,例如:autowire、abstract……若某一个bean的 class 属性没有指定,则该 bean 必须是一个抽象 bean。
depends-on 属性会将 前置依赖的Bean在本Bean实例化之前创建好。如果依赖于多个Bean,则可以通过 逗号、空格 配置Bean的名称。
12.Bean的作用域 : 可以用 scope 属性配置。 singleton 是默认值,容器初始时创建实例,在整个容器生命周期内至创建这一个 bean。 prototype 是原型的,容器初始化时不创建 bean 的实例,而是在每次请求时创建新的 bean实例并返回。
13.可以使用外部属性文件配置Bean。<context:property-placeholder location="classpath: db.source" /> <property name="user" value="${user}">.
14.SpEL : 可以使用 SpEL 来给 Bean 配置 。
(1) 当要给 字符串类型赋值时 : value="#{'abc'}"
(2) 当赋 整型、浮点型时 : value="#{14}" value="#{123.321}"
(3) 当引用其他 属性时 : value="#{car}" value="#{car.price}"
(4) 当引用类的静态属性时: value="#{T(java.lang.Math).PI*8}"
(5) 当使用运算符时: value="#{ 10>5? '大于' : '小于' }"

  1. 可以自行设置 Bean 的 init()方法 和 destroy() 方法。 先在 Bean Class 里将init()和destroy()方法写好,名字自订,然后在xml文件里配置。
    例:

    <bean id="person" class="com.spring.beans.Person" init-method="init3" destroy-method="destroy"></bean>
    

16.可以添加 Bean后置处理器。通过写一个 BeanPostProcessor 接口类,然后在里面重写 postProcessAfterInitialization(init后执行)和postProcessBeforeInitialization(init前执行) 方法,并在xml文件里配置。
例:

 <bean class="com.spring.beans.MyBeanPostProcessor"></bean>

17.可以使用静态工厂方法配置bean:先创建一个静态工厂方法类,例:

public class StaticGameFactory {
private static Map<String,Game> games=new HashMap<String,Game>();
static{
    games.put("ChiJi", new Game("ChiJi",98));
    games.put("H1Z1", new Game("H1Z1",68.0));
}
//静态工厂方法
public static Game getGame(String name){
    return games.get(name);

然后在xml文件里通过静态工厂方法来配置bean。
例:

  <bean id="game" class="com.spring.beans.factory.Game" factory-method="getGame">
<constructor-arg value="cf"></constructor-arg></bean>    //如果工厂方法需要传入参数,则使用constructor-arg来配置参数

18.也可以使用实例工厂方法配置bean:

public class InstanceGameFactory {
private Map<String,Game> games;
public InstanceGameFactory(){
    games=new HashMap<String,Game>();
    games.put("CF", new Game("CF",0));
    games.put("dnf", new Game("dnf",1));
}
public Game getGame(String name){
    return games.get(name);
}

需要先配置工厂的实例:

<bean id="gameFactory" class="com.spring.beans.factory.InstanceGameFactory"></bean>

然后再配置 bean 实例: //factory-bean 指向实例工厂方法的bean factory-method指向实例工厂方法的名字; 如果工厂方法需要传入参数,则使用constructor-arg来配置参数

<bean id="game2" factory-bean="gameFactory" factory-method="getGame"><constructor-arg value="CF"></constructor-arg></bean>

19.通过FactoryBean 来配置 bean。 首先自定义FactoryBean,需要实现FactoryBean 接口,然后在xml文件里 通过 FactoryBean 来配置Bean的实例,例:
class:指向FactoryBean的全类名;property:配置FactoryBean的属性; 实际返回的是 FactoryBean 的 getObejct() 方法的实例

<bean id="game" class="com.spring.beans.factorybeans.GameFactoryBean">
    <property name="name" value="qwe"></property>
</bean>

20.通过注解配置Bean

<!-- 指定Spring IOC 容器扫描的包 -->
<!-- context:component-scan 子节点base-package="" 指定扫描该包及其子包 -->
<!-- 可通过 resource-pattern 指定扫描的资源 -->
<!-- 
<context:component-scan base-package="com.spring.beans.annotation"
    resource-pattern="repository/*.class"
></context:component-scan>
-->
<!-- context:exclude-filter 子节点指定不包含哪些表达式的组件 -->
<!-- context:include-filter 子节点指定包含那些表达式的组件,该节点需要use-default-filters 配合使用(use-default-filters="false")-->
<context:component-scan base-package="com.spring.beans.annotation"
    use-default-filters="true"><!-- type="annotation" 是扫描base-package 包及其所有子包-->
     
<!--
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
 -->
      <!-- type="assignable" 是扫描指定类及implements它的类 -->
 <context:exclude-filter type="assignable" expression="com.spring.beans.annotation.repository.UserRepository" />
</context:component-scan>

使用@Autowired自动装配Bean
一般情况下,所有使用@Autowired注解的属性都要被设置,当Spring找不到匹配的Bean时,会抛出异常,若某一属性允许不被设置,可以设置@Autowired 注解的 required 属性 为fasle。
默认情况下,当IOC容器里存在多个类型兼容的 Bean 时,通过类型的自动装配将无法工作,此时可以在 @Qualifier 注解里提供 Bean 的名称,Spring 允许对方法的形参标注 @Qualifier 以指定注入 Bean 的名称。
--@Autowired 注解也可以应用在 数组类型 的属性上,此时Spring 会把所有匹配的 Bean 进行自动装配。
--@Autowired 注解也可以应用在 集合属性 上,此时Spring 读取该集合的类型信息,然后自动装配所有与之兼容的 Bean。
--@Autowired 注解用在 java.util.Map 上时,若该 Map 的键值为 String ,那么 Spring 将自动装配与之 Map 值类型兼容的 Bean ,此时Bean 的名称作为键值。

21.泛型依赖输入

public class BaseService<T> {
@Autowired
private BaseRepository<T> baseRepository;
public void add(){
    System.out.println("add...");
    System.out.println(baseRepository);
}
}
@Service
public class UserService extends BaseService<User>{
}
@Repository
public class UserRepository extends BaseRepository<User>{
}

当 userService 调用 add 方法时,会输出
add...
com.spring.beeans.generic.di.UserRepository@2449a2da
22.动态配置(AOP基础):

public class ArithmeticCalculatorLoggingProxy {
//要代理的对象
private ArithmeticCalculator target;
public ArithmeticCalculatorLoggingProxy (ArithmeticCalculator target) {
    this.target=target;
}
public ArithmeticCalculator getLoggingProxy(){
    //要代理的对象
    ArithmeticCalculator proxy ;
    //代理对象由哪一个类加载器负责加载
    ClassLoader loader= target.getClass().getClassLoader();
    //代理对象的类型,即其中有哪些方法
    Class[] interfaces=new Class[]{ArithmeticCalculator.class};
    //当调用代理对象其中的方法时,该执行的代码
    InvocationHandler h=new InvocationHandler() {
       @Override
       /*
        * proxy:正在返回的那个代理对象,一般情况下,在 invoke 方法中都不使用该对象
        * method:正在被调用的方法
        * args:调用方法时,传入的参数
        */
       public Object invoke(Object proxy, Method method, Object[] args)
               throws Throwable {
           System.out.println("invoke...");
           //日志
           System.out.println("The method "+method.getName()+" begins with "+Arrays.asList(args));
           //执行方法
           Object result=method.invoke(target, args);
           //日志
           System.out.println("The method "+method.getName()+" ends with "+result);
           return result;
       }
    };
    proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
    return proxy;
  }
}
  public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
public int add(int i, int j) {
    return i+j;
}
public int sub(int i, int j) {
    // TODO Auto-generated method stub
    return i-j;
}
public int mul(int i, int j) {
    // TODO Auto-generated method stub
    return i*j;
}
public double div(double i, double j) {
    return i/j;
}
}
public class Main {
public static void main(String[] args) {
ArithmeticCalculator target=new ArithmeticCalculatorImpl();
ArithmeticCalculator proxy=new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();

System.out.println(proxy.getClass().getName());

int result=proxy.add(1, 2);
System.out.println(result);

result=proxy.sub(3, 1);
System.out.println(result);
}
}  

输出结果为:
com.sun.proxy.$Proxy0
invoke...
The method add begins with [1, 2]
The method add ends with 3
3
invoke...
The method sub begins with [3, 1]
The method sub ends with 2
2
23.(1)SpringAOP
①加入JAR包 ②在配置文件中加入 aop 的命名空间
③基于注解的方式:
i.在配置文件中加入如下配置:

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean class="Aspect.class" /  >
 <!--扫描AOP和代理对象的类-->
 <context:component-scan base-package="com.aop" />

AOP类:

@Aspect
public class LogginPerformance {
   @Pointcut("execution(** com.aop.Performance.perform(..))")
   public void cut() {}
   
   @Before("cut()")
   public void beforeMethod() {
         System.out.println("Before");
   }
}

代理对象类:

package com.aop;
public interface Performance {
     public void perform();
}

还需要讲implements 该接口类的 类 加入扫描对象

package com.aop;
@Component
public class Singer implements Performance{
@Override
public void perform() {
    System.out.println("唱歌");
}
}

使用方法:

package com.aop;
@Component
public class TestAOP {
public static void main(String[] args) {
   ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
   Performance p=ctx.getBean(Performance.class);
   p.perform();
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 229,362评论 6 537
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,013评论 3 423
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 177,346评论 0 382
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,421评论 1 316
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,146评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,534评论 1 325
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,585评论 3 444
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,767评论 0 289
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,318评论 1 335
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,074评论 3 356
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,258评论 1 371
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,828评论 5 362
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,486评论 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,916评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,156评论 1 290
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,993评论 3 395
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,234评论 2 375

推荐阅读更多精彩内容

  • 专题一(1)Spring Framework Runtime 遇到的问题:1,业务代码都使用接口,按照接口编程,能...
    Hughman阅读 592评论 0 3
  • 一、Spring框架 1.1 Spring框架是什么 Spring是一种容器框架,用于配置各个组件(bean)并且...
    Jane_Static阅读 403评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,807评论 18 139
  • 上一篇:Spring学习笔记(三、IoC) ** Bean常用的配置项** Id:在IoC容器中Bean的唯一标识...
    鲁克巴克诗阅读 956评论 0 3
  • 时光匆匆 岁月一直静静地向前流淌着 生命里的那些人来了又走了 但是却一直相信 有些相逢是命中注定 就像茫茫人海中 ...
    佳佳最美阅读 308评论 0 1