spring02课堂笔记

创建对象的三种方式
1,构造器(无参构造器,有参构造器)

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = context.getBean(Book.class);
        System.out.println(bean);
    }

**无参构造器

<bean class="com.offcn.bean.Book">
public Book() {
    System.out.println("无参构造调用了");
    }
输出:
 无参构造调用了
 Book [bid=0, bname=null, bprice=0.0]

**有参构造器

<bean class="com.offcn.bean.Book">
        <constructor-arg name="bid" value="1"></constructor-arg>
        <constructor-arg name="bname" value="红楼梦"></constructor-arg>
        <constructor-arg name="bprice" value="30.2"></constructor-arg>
</bean>
public Book(int bid, String bname, double bprice) {this.bid = bid;
    this.bname = bname;
    this.bprice = bprice;
    System.out.println("有参构造调用了");
}
输出:
有参构造调用了
Book [bid=1, bname=红楼梦, bprice=30.2]


2 静态工厂:通过类的静态方法返回的对象

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = context.getBean(Book.class);
        System.out.println(bean);
    }
}
<bean class="com.offcn.test.StaticFactory" factory-method="getBook"></bean>
public class StaticFactory {
    public static Book getNewstance() {
        Book book = new Book(2,"水浒传",33.53);
        return book;
    }
}
输出:
有参构造调用了
Book [bid=2, bname=水浒传, bprice=33.53]

3实例工厂:通过类对象的普通方法返回的对象

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = context.getBean(Book.class);
        System.out.println(bean);
    }
}
<bean id="getSimpleNewstance" class="com.offcn.test.SimpleFactory"></bean>
<bean factory-bean="getSimpleNewstance" factory-method="getBook"></bean>
public class SimpleFactory {
    public  Book getBook() {
        Book book = new Book(3,"西游记",50);
        return book;
    }
}
输出:
有参构造调用了
Book [bid=3, bname=西游记, bprice=50.0]

给对象的属性赋值的三种方式

三种数据类型:
1.基本类型和String类型
2.其他bean类型(必须是在spring配置文件中出现过的bean)
3.复杂类型(集合类型)

  标签的属性
  //表示给哪个参数赋值
  name:指定参数的set方法名称
  type:指定参数的类型
  index:指定参数的索引位置,从0开始
  //表示给参数具体赋什么值
  value:指定基本数据类型或String类型的数据
  ref:指定其他bean类型数据

1.使用构造器

涉及的标签:<constructor-arg></constructor-arg>

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = (Book)context.getBean("book");
        System.out.println(bean);
    }
}
<bean id="book" class="com.offcn.bean.Book"> 
    <constructor-arg name="bid" value="1" type="java.lang.String"></constructor-arg>
    <constructor-arg name="bname" value="红楼梦"></constructor-arg>
    <constructor-arg name="bprice" value="30.2" index="1"></constructor-arg>
</bean>
public Book(int bid, String bname, double bprice) {
        super();
        this.bid = bid;
        this.bname = bname;
        this.bprice = bprice;
        System.out.println("未更改的有参构造");
    }
    public Book(String bid,double bprice, String bname) {
        super();
        this.bid = Integer.valueOf(bid);
        this.bname = bname;
        this.bprice = bprice;
        System.out.println("更改了参数类型和索引的有参构造");
    }
}
输出:
更改了参数类型和索引的有参构造
Book [bid=1, bname=红楼梦, bprice=30.2]

2.使用set方法

涉及的标签:第一种:<property></property>

扫描二维码关注公众号,回复: 8221848 查看本文章
public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = (Book)context.getBean("book");
        System.out.println(bean);
    }
}
<bean id="book" class="com.offcn.bean.Book">
        <property name="bid" value="2"></property>
        <property name="bname" value="三国演义"></property>
</bean>
public void setBid(int bid) {
        System.out.println("调用了setBid方法");
        this.bid = bid;
}
输出:
调用了setBid方法
Book [bid=2, bname=三国演义, bprice=0.0]

第二种:p名称空间

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = (Book)context.getBean("book");
        System.out.println(bean);
    }
}
xmlns:p="http://www.springframework.org/schema/p"
<bean id="book" class="com.offcn.bean.Book" p:bid="3" p:bname="原来你还在那里" p:bprice="30.90"></bean>
输出:
Book [bid=3, bname=原来你还在那里, bprice=30.9]

3.使用注解

复杂属性注入

数组
列表
集合
Map
properties

@Test
    public void test02() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        FiexList bean = (FiexList)context.getBean("fiexlist");
//        数组类型
        Object[] arr = bean.getArr();
        for (Object object : arr) {
            System.out.println(object);
        }
//        list类型
        List list = bean.getList();
        System.out.println(list);
//        map类型
        Map map = bean.getMap();
        Set<Entry<Object,Object>> entrySet = map.entrySet();
        for (Entry<Object, Object> entry : entrySet) {
            Object key = entry.getKey();
            Object value= entry.getValue();
            System.out.println(key+":"+value);
        }
    }
<bean id="book" class="com.offcn.bean.Book">
        <constructor-arg name="bid" value="20"></constructor-arg>
        <constructor-arg name="bname" value="红楼梦"></constructor-arg>
        <constructor-arg name="bprice" value="30.2"></constructor-arg>
    </bean>
    <bean id="fiexlist" class="com.offcn.bean.FiexList">
        <!-- 数组类型的属性,使用array标签给属性赋值 -->
        <property name="arr">
            <array>
                <value>1</value>
                <ref bean="book"/>
                <bean class="com.offcn.bean.Book">
                    <property name="bname" value="三生三世"></property>
                </bean>
            </array>
        
        </property>
        <!-- list类型的属性,使用list标签给属性赋值 -->
        <property name="list">
            <list>
                <value>2</value>
                <ref bean="book"/>
                <bean class="com.offcn.bean.Book">
                    <property name="bname" value="三生三世"></property>
                </bean>
            </list>
        </property>
        <!-- set属性同数组和list写法一样,使用set标签给属性赋值 -->
        <!-- map类型的属性,使用map标签给属性赋值 -->
        <property name="map">
            <map>
                <entry key="key1" value="value1"></entry>
                <entry key="key2" value="book"></entry>
                <entry key-ref="book" value="value3"></entry>
            </map>
        
        </property>
    </bean>
数组类型和list类型输出:
[2, Book [bid=20, bname=红楼梦, bprice=30.2], Book [bid=0, 
bname=三生三世, bprice=0.0]]

map类型输出:
key1:value1
key2:book
Book [bid=20, bname=红楼梦, bprice=30.2]:value3

IOC注解

1@Component用于创建bean对象的注解

几个常用的创建bean对象的其他注解
@Controller:表示该类对象时控制层【web层】的一个组件
@Service:表示该类对象是在业务逻辑层【service层】的一个组件
@Repository:表示该类对象是在持久化层【dao层】的一个组件

public class App01 {
    @Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book book = (Book)context.getBean("book");
        System.out.println(book);
    }
}
<context:component-scan base-package="com.offcn"></context:component-scan>
//使用注解的时候,该类对象在容器的id值默认为:简类名首字母小写
//也可以通过注解的value属性值设置该类对象在容器的id
@Component("book")
public class Book {
输出:
Book [bid=0, bname=null, bprice=0.0]

2.给对象的属性赋值的注解

@Value给基本类型的属性赋值

@Component("book")
//scope注解相当于xml配置的标签里的scope属性,设置是否为单例
@Scope
public class Book {
    @Value("101")
    private int bid;
    @Value("一本好书")
    private String bname;
    @Value("89.9")
    private double bprice;
输出:
Book [bid=101, bname=一本好书, bprice=89.9]

@Autowire给引用类型的属性赋值,是spring的注解

@Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book book = (Book)context.getBean("book");
        System.out.println(book);
    }
@Component
public class Author {
    private int age;
    private String name;
@Component("book")
//scope注解相当于<bean scope="">标签里的scope属性,设置是否为单例
@Scope
public class Book {
    @Value("101")
    private int bid;
    @Value("一本好书")
    private String bname;
    @Value("89.9")
    private double bprice;
    @Autowired
    private Author author;
输出:
Book [bid=101, bname=一本好书, bprice=89.9, author=Author [age=0, name=null]]

@Resource给引用类型的属性赋值,是jdk自带的

<bean id="at" class="com.offcn.bean.Author"></bean>
public class Book {
    @Value("101")
    private int bid;
    @Value("一本好书")
    private String bname;
    @Value("89.9")
    private double bprice;
    //@Autowired
    @Resource(name="at")
    private Author author;
输出:
Book [bid=101, bname=一本好书, bprice=89.9, author=Author [age=0, name=null]]

说明:
@Autowire:先根据该属性的类型去容器中找该类型的唯一bean对象,如果有唯一bean对象就将该容器中的唯一bean对象赋值给该属性,如果没有,报错,或者容器中有多个该该类型的bean对象,再根据Autowire注解标记的属性名去容器中找,看看容器中的哪个bean对象的id值和该属性名一致,如果有,就将容器中的这个对象赋值给该属性。

 3.加载properties配置文件信息

@Test
    public void test02() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person per = context.getBean(Person.class);
        System.out.println(per);
    
    }

jdbc.properties配置文件内容包含
jdbc.userName=root

<context:component-scan base-package="com.offcn"></context:component-scan>
    <!-- 加载properties配置文件的 -->
   <context:property-placeholder location="classpath:jdbc.properties"/>
@Component
public class Person {
    @Value("${jdbc.userName}")
    private String name;

    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
    
}
输出:
Person [name=root]

Aop

为了将业务逻辑功能的关注点和这些通用化功能的关注点分离开来,就出现了Aop的技术!
通用化功能代码的实现,对应的就是所谓的切面【Aspect】
业务代码和通用功能代码分离之后,责任明确,架构就能变得高内聚低耦合

定义:全称:Aspect Oriented Programming,面向切面编程,和OOP相互促进、相互补充的关系、
  是在OOP原有类代码的基础上,在不改变源代码的前提下,对原有类的功能 进行拓展。
解决:解决了软件工程中提出的关注点分离问题,让不同的部分解决不同的问题。
底层实现:cglib代理 + jdk动态代理
具体应用:声明式事务、缓存、日志处理、全局异常处理。

Aop涉及到的几个重要概念
通知【Advice】:被拓展的功能,称之为通知【本质:方法】
切面【Aspect】:通知所在的类,称之为切面【本质:类】
切入点【PointCut】:指定对谁进行拓展【本质:表达式】
连接点【JoinPoint】:通知 和 目标方法的交点,称之为:连接点
目标对象【Target】:被拓展的类对象,称之为目标对象织入【Weaving】: 将通知 应用到 目标方法的过程,称之为织入

  图解Aop中涉及到的几个概念

Aop的技术实现步骤:
1.导包
2.将被扩展的类和切面类放入容器中【配置扫描包+类上加@Component】

 

3.Spring的配置文件中开启基于注解的切面支持,并在切面类上,加上@Aspect注解

 4.在切面的通知上指定切入点表达式

具体步骤:

package com.offcn.bean;

public interface Caculator {
    public int add(int i,int j);
    public int jian(int i,int j);
    public int cheng(int i,int j);
    public int div(int i,int j);
}
@Component
public class CaculatorImp implements Caculator {
    //方法签名:包名+类名+方法名+参数列表
    @Override
    public int add(int i, int j) {
        int result = i+j;
        System.out.println("目标方法执行了");
        return result;
    }
<context:component-scan base-package="com.offcn"></context:component-scan>
    <!-- 开启基于注解的切面支持 -->
 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Component
@Aspect
public class LogAspect {
    //切入点表达式
    @Before(value="execution(public int com.offcn.bean.CaculatorImp.add(int, int))")
    public void beforeLog() {
        System.out.println("在目标方法执行之前执行");
    }
    @After(value="execution(public int com.offcn.bean.CaculatorImp.add(int, int))")
    public void afterLog() {
        System.out.println("在目标方法执行之后执行");
    }
}
public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Caculator bean = context.getBean(Caculator.class);
        bean.add(3, 4);
        
    }
输出:
在目标方法执行之前执行
目标方法执行了
在目标方法执行之后执行

猜你喜欢

转载自www.cnblogs.com/bai3535/p/12056282.html
今日推荐