Spring配置记录

Spring

https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/core.html#resources

package pojo;

public class Hello {
   private String name;

   @Override
   public String toString() {
       return "Hello{" +
               "name='" + name + '\'' +
               '}';
  }
   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }
}

其中applicationContext.xml

<bean id="hello" class="pojo.Hello">
   <property name="name" value="nxj"></property>
</bean>

如下代码可以看出,ref直接引用一个对象,因此,如果set方法有一个参数,直接就注入了(对象就是引入的对象)

<bean id="ud" class="dao.Impl.UserDaoImpl"></bean>
<bean id="udm" class="dao.Impl.UserDaoMysqlImpl"></bean>

<bean id="us" class="service.Impl.UserServiceImpl">
   <property name="userDao" ref="ud"></property>
</bean>

对应的set为:

public void setUserDao(UserDao ud){userDao=ud;}

 

spring默认使用无参构造构建对象

设置使用有参构造

<!--有参构造-->
<bean id="hello2" class="pojo.Hello2">
   <constructor-arg value="nxj"/>
   <!--或者下方,只能写一个,因为我构造函数最多接受一个参数-->
   <constructor-arg name="name" value="nxj"/>
</bean>

 

配置文件中注册的bean在启动的时候,实例就被创建了,即使你不用它,它也被创建好了在容器中,你想取随时来取,默认取得对象都是同一个。

配置

别名:

<alias name="fromName" alias="toName"/>

 

<!--
id:就是bean的唯一标识
class:就是包名+类名
name:别名
scope:默认是单例实现,我们也可以改成原型
-->
<bean id="hello2" class="pojo.Hello2" name="hello23,heqw" scope="prototype">
   <!--<constructor-arg value="nxj"/>-->
   <constructor-arg name="name" value="nxj"/>
</bean>

针对Propertis,List,Set,Map,数组等我们都可以注入

<bean id="moreComplexObject" class="example.ComplexObject">
   <!-- results in a setAdminEmails(java.util.Properties) call -->
   <property name="adminEmails">
       <props>
           <prop key="administrator">[emailprotected]</prop>
           <prop key="support">[emailprotected]</prop>
           <prop key="development">[emailprotected]</prop>
       </props>
   </property>
   <!-- results in a setSomeList(java.util.List) call -->
   <property name="someList">
       <list>
           <value>a list element followed by a reference</value>
           <ref bean="myDataSource" />
       </list>
   </property>
   <!-- results in a setSomeMap(java.util.Map) call -->
   <property name="someMap">
       <map>
           <entry key="an entry" value="just some string"/>
           <entry key ="a ref" value-ref="myDataSource"/>
       </map>
   </property>
   <!-- results in a setSomeSet(java.util.Set) call -->
   <property name="someSet">
       <set>
           <value>just some string</value>
           <ref bean="myDataSource" />
       </set>
   </property>
</bean>

 

C命名空间和p命名空间

<!--
在xml头需要引入
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:c="http://www.springframework.org/schema/c"
-->

<bean id="user" class="com.jd.nxj.pojo.User" p:name="nxj" p:age="23" p:desc="p就是properties的意思"/>
<bean id="user2" class="com.jd.nxj.pojo.User" c:age="25" c:name="qwe" c:desc="wodetian" p:name="nxj" p:age="23"></bean>

 

自动装配

byName:在容器上修啊文中查找和自己方法中set后面相同名字的id(bean)【如setCat 则找有没有bean的名字和cat一致,如果有则成功注入(必须小写)】

byType:在容器上下文中查找和自己对象属性类型相同的bean

<bean id="cat1" class="com.jd.nxj.Cat"/>
<!--以上因为名字为cat1,与setCat 后cat不同,找不到,因此报错!-->
<bean id="person" class="com.jd.nxj.Person" autowire="byName">
   <property name="name" value="nxj"/>
</bean>

 

<bean id="cat" class="com.jd.nxj.Cat"/>
<bean id="cat2" class="com.jd.nxj.Cat"/>
<!--以上因为两个bean的class和我需要注入的Cat类型相同,因此无法判断注入哪个,报错!-->
<bean id="person" class="com.jd.nxj.Person" autowire="byType">
   <property name="name" value="nxj"/>
</bean>

 

@AutoWaired

需要在配置文件中加入点东西,包括头部信息和一行属性,代表我要开启自动配置的功能

@Qualifier(value = "dog2") //指定自动装配的beanid

@Resource 这个更高级

他不是spring下的,而是javax下的 类名匹配唯一,则他就是byType,名字唯一则就是byName ,当然通过name属性达成与@Qualifier相同的功能,强大!!!!

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
   
##这个就是我要开启自动配置的功能
   <context:annotation-config/>    
   

   <bean id="cat" class="com.jd.nxj.Cat"/>
   <!--<bean id="cat2" class="com.jd.nxj.Cat"/>-->
  ## @Autowaired默认是按照byName方式注入的,因此如果beanid和我的set后面单词变成小写不相同,则注入失败,报错
   <bean id="dog" class="com.jd.nxj.Dog"/>
   

   <bean id="person" class="com.jd.nxj.Person" autowire="byType"><!--p:cat-ref="cat" p:dog-ref="dog" p:name="nxj"-->
       <property name="name" value="nxj"/>
   </bean>

   <bean id="person2" class="com.jd.nxj.Person">
       <property name="name" value="nxj"/>
   </bean>

</beans>
@Autowired需要在Spring的bean的容器中才生效,因为person的类路径配置在了ioc容器中,我们通过classpathxml方式获取出来,因此生效,如果我们获取的并不在ioc容器中,那么一定无效,这点一定要记住,后面的springboot中的@Autowaired也是这样对吧!)
//在set方法上注入,这样就将dog注入进来了(默认是byType方式注入的)
@Autowired
public void setDog(Dog dog) {
   this.dog = dog;
}

//或者在Person中
@Autowired
@Qualifier(value = "dog2")  //指定自动装配的beanid
private Dog dog;
@Resource(name = "cat1")
private Cat cat;

 

@Repository
@Service

@Component

在Spring中@Component,需要配置注解能使用,并且需要在配置文件中扫描到当前包,才能使用

使用ClassPathXmlApplicationContext 这个是针对于配置文件的

new ClassPathXmlApplicationContext("applicationContext.xml")
//如果失败就下面这样写(哪个都行)
new ClassPathXmlApplicationContext("file:E:\Code\2020\inJDstudy\spring-test\02-Spring\src\main\resources")
ApplicationContext context=new FileSystemXmlApplicationContext("src/main/resources/beans.xml");

ApplicationContext context=new FileSystemXmlApplicationContext("src/main/resources/beans.xml");

@Configuration

这是目前是spring推荐使用的方式

@Configuration代表这是一个配置类,把它看成applicationContext.xml就好了!!!

此时就是基于注解的

ApplicationContext context = new AnnotationConfigApplicationContext("com.jd.nxj.config");
Person person = context.getBean("person", Person.class);
      System.out.println(person.getName());

config:

@Configuration
public class TestConfig {
  //@Bean对应于<bean>标签
  //方法名person对应于bean的id
  //返回值对应bean的class
  @Bean
  public Person person(){
      //若person标注@Value了,这里即使赋值也是无效的!
      return new Person("aaa");
  }
}

component

@Component
public class Person {
  @Value("qwe")
  private String name;

  public Person() {
  }
  public Person(String name) {
      this.name=name;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }
}

把它看成applicationContext.xml是没问题的,比如在config上加@ComponentScan("com.jd.nxj.pojo"),那么即使我不在config中配置person的bean,在person直接@Component也是可以直接生效的

@Import 对应底层import标签,组合进来一起使用

 

 

动态代理

动态代理代理的是一类业务

InvocationHandler:调用代理程序并处理返回结果

Proxy:获取代理对象

public class DynamicProxy implements InvocationHandler {
   //要被代理的对象
   private Rent rent;

   public void setRent(Rent rent) {
       this.rent = rent;
  }
   //<T> T getBean(String var1, Class<T> var2) throws BeansException;
   //获取代理类对象
   public <T> T getProxy(Class<T> var){
       return (T)Proxy.newProxyInstance(rent.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
  }

   //调用代理的方法时会触发下方Inoke方法
   @Override
   public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
       Object res = method.invoke(rent, objects);
       return res;
  }
}

AOP

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.6</version>
   <scope>runtime</scope>
</dependency>

方式一:

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd">
   <!--注册bean-->
   <bean id="userService" class="com.jd.nxj.service.UserServiceImpl"/>
   <bean id="beforelog" class="com.jd.nxj.BeforeLog"/>
   <bean id="afterlog" class="com.jd.nxj.AfterLog"/>

   <!--使用原生Spring API接口-->
   <!--配置aop-->
   <aop:config>
       <!--切入点-->
       <aop:pointcut id="pointcut" expression="execution(* com.jd.nxj.service.UserService.*(..))"/>
       
       <!--执行环绕增加-->
       <aop:advisor advice-ref="beforelog" pointcut-ref="pointcut"/>
       <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
   </aop:config>
</beans>

两个前后置方法

public class AfterLog implements AfterReturningAdvice {
   @Override
   public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
       System.out.println("AfterReturningAdvice被触发");
  }
}


public class BeforeLog implements MethodBeforeAdvice {
   @Override
   public void before(Method method, Object[] objects, Object target) throws Throwable {
       System.out.println("MethodBeforeAdvice触发");
       //System.out.println(target.getClass().getName()+"的"+method.getName()+"被触发");
  }
}

service

public interface UserService {
   void method1();

   void method2();
}

impl

public class UserServiceImpl implements UserService {
   @Override
   public void method1() {
       System.out.println("~~~");
  }

   @Override
   public void method2() {
       System.out.println("!!!");
  }
}

调用:

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //这里必须是接口,因为jdk底层实现动态代理依赖的是接口
        UserService userService = context.getBean("userService", UserService.class);
        userService.method1();
    }
}

方式二:

因为自定义方法,无法获取上方继承如AfterReturningAdvice 这样,获取更多的信息

<!--方式二:自定义类-->
<bean id="diy" class="com.jd.nxj.diy.DiyPointCut"/>
<aop:config>
    <!--自定义切面-->
    <aop:aspect ref="diy">
        <!--切入点-->
        <aop:pointcut id="pointcut2" expression="execution(* com.jd.nxj.service.UserService.*(..))"/>
        <!--通知-->
        <aop:before method="before" pointcut-ref="pointcut2"/>
        <aop:after method="after" pointcut-ref="pointcut2"/>
    </aop:aspect>
</aop:config>
public class DiyPointCut {
    public void before(){
        System.out.println("before");
    }
    public void after(){
        System.out.println("after");
    }
}

 

注解版的修改了,暂时不看了,理解下前面学的哈!!!

整合Myatis

(必须要导入依赖)

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.5</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
    <scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
    <scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

1.配置数据源

2.配置sqlSessionFactory

3.配置sqlSession 也就是SqlSessionTemplate

4.可以使用,也就是注册bean了,但是这里对应每个mapper还必须有对应的实现类,内部聚合SqlSessionTemplate,使用set注入,将sqlSession注入进去。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://47.98.189.228:3306/testdb"/>
     </bean>

    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--绑定mybatis配置文件(如果有Xml的话)-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--这里可以写配置文件中基本上所有的(但是有的时候还是xml方便些)-->
<!--        <property name="typeAliases" value="com.jd.nxj.pojo.User"/>-->
        <!--所有mapper与配置文件的映射-->
        <property name="mapperLocations" value="classpath:com/jd/nxj/mapper/*.xml"/>
    </bean>

    <!--sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>

    <!--使用(通过sessionTemplate其实就是构建sqlSession了)-->
    <bean id="userMapper" class="com.jd.nxj.mapper.impl.UserMapperImpl">
        <property name="sessionTemplate" ref="sqlSession"/>
    </bean>
</beans>

 

SqlSessionDaoSupport

SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法,就像下面这样:

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

在这个类里面,通常更倾向于使用 MapperFactoryBean,因为它不需要额外的代码。但是,如果你需要在 DAO 中做其它非 MyBatis 的工作或需要一个非抽象的实现类,那么这个类就很有用了。

SqlSessionDaoSupport 需要通过属性设置一个 sqlSessionFactorySqlSessionTemplate。如果两个属性都被设置了,那么 SqlSessionFactory 将被忽略。

假设类 UserMapperImplSqlSessionDaoSupport 的子类,可以编写如下的 Spring 配置来执行设置:

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

 

Spring事务的保证是,在容器中保证的,也就是说,你执行的方法是容器中的,而不能是你外部自己搞个方法写,这是其一;

其二注册组件使用事务,那么这个组件所在的配置文件位置最少要包含,也就是可达这个事务,如注册组件在a.xml中,那么事务可以在这里配,或者在外部配,然后import进来 这样是可以的。【如果事务的配置文件为b.xml,b.xml中导入a.xml,这样就无法使用事务!!】

posted @ 2020-11-14 09:07  程序杰杰  阅读(296)  评论(0编辑  收藏  举报