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);
    }

**无参构造器

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

**有参构造器

class="com.offcn.bean.Book">
        
        
        
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");
     StaticFactory bean = context.getBean(StaticFactory.class);
     System.out.println(bean); }
  }
class="com.offcn.test.StaticFactory" factory-method="getBook">
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");
        SimpleFactory bean = context.getBean(SimpleFactory.class);
        System.out.println(bean);
    }
}
class="com.offcn.test.SimpleFactory">
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.使用构造器

涉及的标签:

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = (Book)context.getBean("book");
        System.out.println(bean);
    }
}
class="com.offcn.bean.Book"> 
    
    
    
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方法

涉及的标签:第一种:

public class App01 {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book bean = (Book)context.getBean("book");
        System.out.println(bean);
    }
}
class="com.offcn.bean.Book">
        
        
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"
class="com.offcn.bean.Book" p:bid="3" p:bname="原来你还在那里" p:bprice="30.90">
输出:
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> entrySet = map.entrySet();
        for (Entry entry : entrySet) {
            Object key = entry.getKey();
            Object value= entry.getValue();
            System.out.println(key+":"+value);
        }
    }
class="com.offcn.bean.Book">
        
        
        
    
    class="com.offcn.bean.FiexList">
        
        
            
                1
                
                class="com.offcn.bean.Book">
                    
                
            
        
        
        
        
            
                2
                
                class="com.offcn.bean.Book">
                    
                
            
        
        
        
        
            
                
                
                
            
        
        
    
数组类型和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);
    }
}
package="com.offcn">
//使用注解的时候,该类对象在容器的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注解相当于标签里的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自带的

class="com.offcn.bean.Author">
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

package="com.offcn">
    
   
@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中涉及到的几个概念

spring02_第1张图片

 

 

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

 

 spring02_第2张图片

 

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

 

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

spring02_第3张图片

 

具体步骤:

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;
    }
package="com.offcn">
    
 
@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);
        
    }
输出:
在目标方法执行之前执行
目标方法执行了
在目标方法执行之后执行

你可能感兴趣的:(spring02)