package com.example.demospring1;

import com.example.demospring1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.lang.reflect.Field;





/**
 * @description:
 * @author: 范子祺
 **/
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = (UserService)context.getBean("userService");
//测试2  依赖注入
        userService.test();
//结果2 orderService seecom.example.demospring1.service.OrderService@1e67a849




//测试1 默认都是单例bean
//        UserService userService1 = (UserService)context.getBean("userService");
//        UserService userService2 = (UserService)context.getBean("userService");


//        System.out.println(userService);
//        System.out.println(userService1);
//        System.out.println(userService2);
        //结果1
//        com.example.demospring1.service.UserService@1e67a849
//        com.example.demospring1.service.UserService@1e67a849
//        com.example.demospring1.service.UserService@1e67a849

//        UserService userService3 = new UserService();
//        context.getBeanFactory().registerSingleton("xxx",userService3);

//        UserService userService1 = new UserService();
//
//        for (Field field: userService1.getClass().getDeclaredFields()){
//            if (field.isAnnotationPresent(Autowired.class)){
//                field.set(userService1,??);
//            }
//        }

    }
}
@ComponentScan("com.example.demospring1")
public class AppConfig {
}


@Component
public class UserService {

    @Autowired
    private OrderService orderService;

    public void test(){
        System.out.println("orderService see"+orderService);
    }
}


@Component
public class OrderService {
}

  

1 依赖注入,2 单例bean,

userservice类->无参构造函数->对象->依赖注入->初始化->放入Map单例池->bean对象

 

希望使用类的时候,它里面的某个属性,已经从数据库中取到值了

userservice中增加

@PostConstruct
    public void a(){
        System.out.println("初始化前");
    }
结果

14:24:27.525 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
初始化前
orderService seecom.example.demospring1.service.OrderService@75f9eccc

继续增加

public class UserService implements InitializingBean {



@PostConstruct
    public void a(){
        System.out.println("初始化前-PostConstruct");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化前-afterPropertiesSet");
    }


结果
14:28:19.050 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
初始化前-PostConstruct
初始化前-afterPropertiesSet
orderService see:com.example.demospring1.service.OrderService@5d47c63f

 构造函数的证明

类UserService 增加

public UserService() {
        System.out.println("空参构造函数:"+orderService);
    }

    public UserService(OrderService orderService) {
        this.orderService = orderService;
        System.out.println("1个入参orderService构造函数:"+orderService);
    }
结果
空参构造函数:null
初始化前-PostConstruct
初始化前-afterPropertiesSet
orderService see:com.example.demospring1.service.OrderService@5d47c63f

 自动选择了无参构造函数

OrderService 增加

 public OrderService() {
        System.out.println("空参OrderService"+this);
    }

UserService  修改

//    public UserService() {
//        System.out.println("空参构造函数:"+orderService);
//    }

    public UserService(OrderService orderService) {
        this.orderService = orderService;
        System.out.println("1个入参的UserService构造函数:"+orderService);
    }


结果

17:49:18.193 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
空参OrderServicecom.example.demospring1.service.OrderService@1445d7f
17:49:18.198 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
17:49:18.365 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'userService' via 
constructor to bean named 'orderService' 1个入参的UserService构造函数:com.example.demospring1.service.OrderService@1445d7f 初始化前-PostConstruct 初始化前-afterPropertiesSet orderService see:com.example.demospring1.service.OrderService@1445d7f

 

1 依赖注入, 2 单例bean

UserService增加

public UserService(OrderService orderService1,OrderService orderService2) {
        this.orderService = orderService;
        System.out.println("2个入参的UserService构造函数:"+orderService);
        System.out.println("2个入参的UserService构造函数h2:"+orderService1+"="+orderService2);
    }

结果
17:53:44.235 [main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext - 
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.
BeanCreationException: Error creating bean with name 'userService' defined in file [/Users/shenshaonian/Desktop/selfPro/spr
ing/demoSpring1/target/classes/com/example/demospring1/service/UserService.class]: Instantiation of bean failed; nested exc
eption is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.demospring1.service.U
serService]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.example.demospring1.service.UserService.<init>()

多个有参的构造函数,无法判断使用哪个构造函数创建对象

UserService  修改

//    public UserService(OrderService orderService) {
//        this.orderService = orderService;
//        System.out.println("1个入参的UserService构造函数:"+orderService);
//    }

public UserService(OrderService orderService1,OrderService orderService2) {
        this.orderService = orderService;
        System.out.println("2个入参的UserService构造函数:"+orderService);
        System.out.println("2个入参的UserService构造函数h2:"+orderService1+"="+orderService2);
    }

public void test(){
        orderService.orderServicePrint();
        System.out.println("userservice look orderService see:"+orderService+"==");
    }


OrderService 增加
public void orderServicePrint(){
        System.out.println("orderServicePrint look");
    }


结果空参
OrderServicecom.example.demospring1.service.OrderService@1445d7f
18:01:15.133 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
18:01:15.236 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'userService' via constructor to bean named 'orderService'
2个入参的UserService构造函数:null
2个入参的UserService构造函数h2:com.example.demospring1.service.OrderService@1445d7f=com.example.demospring1.service.OrderService@1445d7f
初始化前-PostConstruct
初始化前-afterPropertiesSet
orderServicePrint look
userservice look orderService see:com.example.demospring1.service.OrderService@1445d7f==

1 autowire注释的bean一般会在对象使用的时候才会实例化,2 对象放到构造函数的参数中也是一种提前的实例化, 最终orderservice的地址都是

1445d7f, 这里面是通过cglib代理实现的, cglib是啥, asm是啥, 这里我有点搞不清了。 可能有错误的地方。

 

修改  UserService

 @Autowired
    public UserService(OrderService orderService1,OrderService orderService2) {
        this.orderService = orderService;
        System.out.println("2个入参的UserService构造函数orderService="+orderService);
        System.out.println("2个入参的UserService构造函数orderService1="+orderService1+"orderService2="+orderService2);
    }


增加

AppConfig

@Bean
    public OrderService orderService1(){
        return new OrderService();
    }

    @Bean
    public OrderService orderService2(){
        return new OrderService();
    }


增加 Test

OrderService orderService = (OrderService)context.getBean("orderService");
        OrderService orderService1 = (OrderService)context.getBean("orderService1");
        OrderService orderService2 = (OrderService)context.getBean("orderService2");

        System.out.println("test orderService:"+orderService);
        System.out.println("test orderService1:"+orderService1);
        System.out.println("test orderService2:"+orderService2);


结果

21:59:32.974 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
空参OrderServicecom.example.demospring1.service.OrderService@7bc1a03d
21:59:32.975 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
21:59:33.142 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService1'
空参OrderServicecom.example.demospring1.service.OrderService@18a70f16
21:59:33.175 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService2'
空参OrderServicecom.example.demospring1.service.OrderService@c8e4bb0
21:59:33.183 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'userService' via constructor to bean named 'orderService1'
21:59:33.184 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'userService' via constructor to bean named 'orderService2'
2个入参的UserService构造函数orderService=null
2个入参的UserService构造函数orderService1=com.example.demospring1.service.OrderService@18a70f16orderService2=com.example.demospring1.service.OrderService@c8e4bb0
初始化前-PostConstruct
初始化前-afterPropertiesSet
orderServicePrint look
userservice look orderService see:com.example.demospring1.service.OrderService@7bc1a03d==
test orderService:com.example.demospring1.service.OrderService@7bc1a03d
test orderService1:com.example.demospring1.service.OrderService@18a70f16
test orderService2:com.example.demospring1.service.OrderService@c8e4bb0

 

OrderService@7bc1a03d
OrderService@18a70f16  orderservice1
OrderService@c8e4bb0   orderservice2
这里是实例化了三个orderservice的bean ,可以推断出,spring是bytype + byname的

 

 证明确实bynam了

 

 

 

证明使用了byname

再次根据我们上面没有在appconfig中注入bean的时候,我们的orderservice打出来的地址是一样的,说明, class的类型只有一个bean的时候,是直接取bytype判断的,和bean的name

无关

 

所以单例模式,单例bean,根本就是在讲目的不同的两件事

 

aspect

 

 结合下面的代码看, 1 orderservice还没初始化,2 aop使用的是cglib

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = (UserService)context.getBean("userService");

        userService.test();



@ComponentScan("com.example.demospring1")
@EnableAspectJAutoProxy
public class AppConfig {




@Component
public class UserService implements InitializingBean {
    @Autowired
    private OrderService orderService;

    @PostConstruct
    public void a(){
        System.out.println("初始化前-PostConstruct");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化前-afterPropertiesSet");
    }

    public void test(){
        //orderService.orderServicePrint();
        System.out.println("userservice look orderService see:"+orderService+"==");
    }



@Component
public class OrderService {
    public OrderService() {
        System.out.println("空参OrderService"+this);
    }

    public void orderServicePrint(){
        System.out.println("orderServicePrint look");
    }
}




@Aspect
@Component
public class TestAspect {

    @Before("execution(public void com.example.demospring1.service.UserService.test())")
    public void testUserBefore(JoinPoint joinPoint){
        System.out.println("class: TestAspect"+"method: testUserBefore");
    }
}

 


userservice类->推断构造函数->普通对象->依赖注入->初始化前(postconstruct)->初始化(initializingBean)->初始化后(aop)->代理对象->放入Map单例池->bean对象

 重新断点, 摆出问题:

 

 外面两个orderservice, 到里面的orderservice 

cglib 是基于父子类的 

推测一 伪代码

 

 

 

 super.test()的问题这里没有讲透。  视频里面想说的应该是,第一层我们看见的代理对象userservice有值,但是里面的orderservice无值, 而实际上我们调用进去的时候,发现orderservcie又有值了。

代理对象找到真的userservice对象,调用test,test里面使用到了orderservice, 而真正实例化的两个类没有到管理bean的map中, 是通过代理对象钩子的方式唤起真正的对象去做事情。就好像生活中,张三找王五去买一头牛一样,张三买牛,王五卖牛,这个时候大多数我们都要经过一次市场,假设我们通过市场的刘麻子买牛, 这个时候刘麻子知道谁卖牛,于是刘麻子就让张三去找王五买牛。凡是要买牛卖牛的大家都可以来找刘麻子。

 

 

 

 com.example.demospring1.service.UserService@33aeca0b    代理对象userserviceProxy

普通对象userservice是 2749  普通对象orderservice是2750

 

 

 

 

 

 

 

纯纯的中介思想哈哈哈哈哈

spring的事务



代码

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = (UserService)context.getBean("userService");

        userService.test();




@ComponentScan("com.example.demospring1")
//@EnableAspectJAutoProxy
@EnableTransactionManagement
@Configuration // 自动帮我们把下面几个的关系装配好, 描述不完全准确,你可以自己去掉这个看一下报错
public class AppConfig {


    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource());
        return manager;
    }

    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("1234qwer");
        return dataSource;
    }





@Component
public class UserService  {

    @Autowired
    private JdbcTemplate jdbctemplate;

    @Autowired
    UserService userService;

    @Transactional
    public void test(){
        jdbctemplate.execute("insert into user(name,age,sex, addr) values('测试3',100,1,'测试地址')");
        userService.a();
      //a();
// throw new NullPointerException();  } ///继续学习其他的 spring的事务和相关的面试题 @Transactional(propagation = P
//ropagation.NEVER)
public void a(){ jdbctemplate.execute("insert into user(name,age,sex, addr) values('测试2',100,1,'测试地址')"); // throw new NullPointerException(); }



结果
Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'

 

注意:
userService.a();
      //a();
注意:上面这个两个方法, userService调用的时候是失败的,never生效了, 而a()调用是成功的。    原因是:userService掉用的时候,实际是代理对象去掉的, 而trans的注解, aop思想切的所关注的也是这个代理对象。
普通对象,切面方法是没有关注他的。 我们可以通俗的理解为, 加了事务注解,这个时候,事务实际上关注的是你这个代理人, 你这个代理如果之前启用过事务了, 后面这个代理再启用事务的时候,发现有个never,那这个时候监控到了,直接抛错,
而普通对象,别人跟你没得关系,不监控你。
同理想让它事务生效, 拆个新类,调用测试,一样的生效。