天天看點

spring 架構介紹一下spring架構:spring核心思想的介紹:Spring環境搭建:spring核心配置檔案的詳解:

之前分享過hibernate架構, 這次分享一下關于spring架構的一些内容,都是自我了解的一些内容,僅供參考哦。

首先

介紹一下spring架構:

Spring是一個開源架構,是一個一站式架構

Spring是一個容器,你給他安裝什麼,他就擁有了什麼功能

Struts2他就是一個web層,給他安裝hibernate他就是一個dao層的架構。Service也可以使用spring架構來管理。

Spring  springMVC  springBoot都是web層的架構

     JbdcTemplate  spring中也提供了dao層的架構

spring核心思想的介紹:

Ioc  (控制反轉)

Di  (依賴注入) (技術點)

Aop  (面向切面)  事務的管理

簡單的對spring有一些了解之後,就是如何對spring的環境搭建:

Spring環境搭建:

  1. 導包(需要導入三個依賴:)
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    
    </dependencies>
               
  2. 然後再準備一個類
  3. 書寫配置檔案(applicationContext.xml)   引入限制    配置實體類,在spring容器中
  4. 書寫測試代碼
    public class Demo {
        public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            User user = (User) ac.getBean("user");
            System.out.println(user);
    
        }
               

    spring核心配置檔案的詳解:

1. 名字和位置

配置檔案名字沒有要求,

位置:maven 放在resource中

2. bean 屬性的配置

功能:配置類  用來建立對象

Class

Name

建立對象的方式:

a) 通過無參的構造函數來建立(預設)

b)通過靜态工廠來執行個體化對象

   提供靜态工廠   類中提供一個靜态方法,傳回一個實體對象

public class UserFactory {
    public static User createUser(){
        return new User();
    }
           

配置檔案:

<bean name="userFactory" class="com.hd.create.UserFactory" factory-method="createUser"></bean>
           

測試類:

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) ac.getBean("userFactory");
        System.out.println(user);
}
           

c) 通過執行個體化工廠建立對象

    準備一個工廠   提供建立對象的方法  public

    配置檔案中,既要配置要建立的對象,也要配置工廠

    在對象的建立時要指定是哪個工廠中的方法

spring 架構介紹一下spring架構:spring核心思想的介紹:Spring環境搭建:spring核心配置檔案的詳解:

spring屬性注入:

1. set方法注入(重點)

基礎類型  8大基礎類型和string value注入

<bean name="car" class="com.hd.injection.Car">
        <property name="name" value="加長林肯"></property>
        <property name="color" value="黑色"></property>
</bean>
           

引用類型  對象 ref注入

<bean name="user" class="com.hd.test.User">
<property name="name" value="郭婷婷"></property>
<property name="address" value="河南"></property>
<property name="userId" value="0123"></property>
<property name="car" ref="car"></property>
</bean>
           

2. 構造函數的注入

建立對象用的是制定構造函數建立(按照順序進行注入)

name (構造函數中參數的名字) value(屬性的值) index(該參數的位置) type(該參數的類型)

<constructor-arg name="age" value="12" index="0" type="java.lang.Integer"></constructor-arg>
           

3. p空間的注入

導入限制

spring 架構介紹一下spring架構:spring核心思想的介紹:Spring環境搭建:spring核心配置檔案的詳解:

這種方式雖然簡單,但是不被業界認可

4. spel 注入

<bean name="teacher1" class="com.hd.injection.TeacherP">
        <property name="name" value="#{teacher.name}"></property>
</bean>
           

适用于已經在spring容器中有一個對象,重新建立一個對象要用到原來對象中的内容

複雜屬性的注入:

數組屬性注入:

數組屬性注入

    <bean name="order" class="com.hd.complexInjection.Order">
        <property name="productIds">
            <array>
                <value>1</value>
                <value>2</value>
                <value>3</value>
                <value>4</value>
            </array>
        </property>
           

集合:

list Map

<property name="list">
            <list>
                <value>list集合</value>
                <ref bean="car"></ref>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="id" value="1123"></entry>
                <entry key="car" value-ref="car"></entry>
            </map>
        </property>
           

Properties

<property name="properties">
            <props>
                <prop key="url">jdbc:mysql:localhost:3306</prop>
            </props>
        </property>
    </bean>
           

注解方式:

1. 開啟注解   制定掃描的包

<context:component-scan base-package="com.hd"></context:component-scan>
           

2. 使用注解管理對象

@Component   //以下三合一注解

@Repository  //dao層注解

@Service

@Controller //外部層注解

四種注解,沒有本質差別,隻是為了區分web項目的結構

如果想給對象起個名字在上面小括号中寫入名字即可,如果不寫預設與類型保持一緻(首字母小寫)

3. 對象的範圍

@Scope(scopeName = "prototype")
           

在類上面進行書寫

4. 在建立對象後和銷毀對象前調用的方法

@PostConstruct
public void init(){
    System.out.println("建立對象後調用");
}
@PreDestroy
public void destroy(){
    System.out.println("銷毀對象前調用");
}
           

5. 依賴管理

普通屬性

在屬性或者set方法上面注解

@Value("張三")//在屬性上面注解,  set方法可以省略
private String name;
private Integer age;
或者

@Value("21")
public void setAge(Integer age) {
    this.age = age;
}
           

引出類型:

如果該對象在spring中隻有一個

@Autowired
 private Car car;
           

如果有多個還想使用自動裝配,就必須指定

@Autowired
    @Qualifier("car2")
    private Car car;
           
如果是多個寫兩個比較麻煩,提供一個新的
           
@Resource(name = "car2")
private Car car;
           

Spring結合Junit測試:

導包

Maven項目依賴
           
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
    <scope>test</scope>
</dependency>
           

Spring AOP:

Aop

面向切面程式設計

Spring aop的原理

代理技術:spring aop用到了java中代理技術,給目标對象生成一個代理對象,生成的目标對象會擁有目标對象的所有方法,隻要在調用目标對象方法前執行代理對象代碼即可。

Spring 實作代理有兩種方式:

  1. 動态代理(優先考慮): 該目标對象必須實作接口,才能生成代理對象
  2. Cglib 代理: 不用實作接口,第三方代理技術,實作代理技術原理是使用繼承,要求目标對象不能使用final修飾。

手動實作代理動态代理:

加強service   開啟事務  送出事務

  1. 準備一個service接口
  2. 實作service接口
  3. 建立service的代理對象工廠

Spring 實作代理有兩種方式:

1. 動态代理(優先考慮): 該目标對象必須實作接口,才能生成代理對象

2. Cglib 代理: 不用實作接口,第三方代理技術,實作代理技術原理是使用繼承,要求目标對象不能使用final修飾。

手動實作代理動态代理:

加強service   開啟事務  送出事務

  • 準備一個service接口
  • 實作service接口
  • 建立service的代理對象工廠
public class UserServiceProxyFactory  implements InvocationHandler{
    private UserService userService;
    public UserServiceProxyFactory(UserService userService) {
        this.userService = userService;
    }
    public UserService getUserServiceProxy() {
        UserService  userServiceProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                UserServiceImpl.class.getInterfaces(), this);
        return userServiceProxy;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("開啟事務");
        Object invoke = null;
        try{
            invoke= method.invoke(userService,args);
            System.out.println("送出事務");
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("復原事務");
        }

        return invoke;
    }
}
           

cgilb實作代理方法:

  1. 準備一個類
  2. 建立生成代理對象的類
public class UserServiceProxyFactory1 implements MethodInterceptor{
    public UserService getUserServiceProxy(){
        //cglib  提供的api 用來建立代理對象
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserServiceImpl.class);
        enhancer.setCallback(this);
        UserService o = (UserService) enhancer.create();
        return o;
    }
@Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("開啟事務");
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println("送出事務");
        return invoke;
    }
           

SpringAop:

7個專業名詞:

連接配接點   joinPoint  被代理對象擁有所有可以加強的方法

切入點   pointCut  已經被加強的方法

通知     adivce    加強的代碼

目标對象  target   被代理的對象

織入     weaving    将通知應用到目标對象的連接配接點

代理   proxy   生成目标對象的代理對象

切面   aspect  通知+切點

1. 導包(aspect)

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.12</version>
        </dependency> 
           

2. 準備一個通知

3. 配置切點和切面

<context:component-scan base-package="com.hd"></context:component-scan>
<bean name="myAdvice" class="com.hd.springAop.MyAdvice"></bean>
<aop:config>
<aop:pointcut id="pt" expression="execution( * com.hd.springAop.*ServiceImpl.*(..) )"></aop:pointcut>
<aop:aspect ref="myAdvice">
    <aop:before method="before" pointcut-ref="pt"></aop:before>
    <aop:after method="after" pointcut-ref="pt"></aop:after>
    <aop:after-returning method="afterReturning" pointcut-ref="pt"></aop:after-returning>
    <aop:after-throwing method="afterThrowing" pointcut-ref="pt"></aop:after-throwing>
</aop:aspect>
</aop:config>
           
  1. 開啟注解模式
  2. 在通知中使用注解配置
@Before("MyAdvice.pt()")
public void before(){
    System.out.println("注解模式---方法前使用");
}

@After("MyAdvice.pt()")
public void after(){
    System.out.println("有異常也正常調用");
}
           

Spring整合JDBC

Spring是一個容器

Dao層   hibernate  mybatis jdbcTemplate

  1. 導包  spring-jdbc   資料庫驅動包 c3p0連接配接池 spring-tx
  2. 準備好資料庫

手動管理對象測試代碼:

1)獲得資料庫連接配接   連接配接池

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/springjdbc?CharacterEncoding=UTF-8");
dataSource.setUser("root");
dataSource.setPassword("root");
           

2)獲得springjdbc提供的api jdbcTemplate

JdbcTemplate jt = new JdbcTemplate();
jt.setDataSource(dataSource);
           

3)調用JdbcTemplate方法

String  sql = "insert into t_user VALUE (null,'王','199')";

int update = jt.update(sql);
System.out.println(update);
           

Spring 容器管理對象的方式開啟dao方法

Spring管理事務

事務的傳播行為 propagation

1、PROPAGATION_REQUIRED:如果目前沒有事務,就建立一個新事務,如果目前存在事務,就加入該事務,該設定是最常用的設定。

2、PROPAGATION_SUPPORTS:支援目前事務,如果目前存在事務,就加入該事務,如果目前不存在事務,就以非事務執行。‘

3、PROPAGATION_MANDATORY:支援目前事務,如果目前存在事務,就加入該事務,如果目前不存在事務,就抛出異常。

4、PROPAGATION_REQUIRES_NEW:建立新事務,無論目前存不存在事務,都建立新事務。

5、PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果目前存在事務,就把目前事務挂起。

6、PROPAGATION_NEVER:以非事務方式執行,如果目前存在事務,則抛出異常。

7、PROPAGATION_NESTED:如果目前存在事務,則在嵌套事務内執行。如果目前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

配置xml:

<tx:advice id = "myAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transform" isolation="DEFAULT" rollback-for="false" propagation="REQUIRED"/>
        </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="myPt" expression="execution(* com.hd.jdbc.*ServiceImpl.*(..))"></aop:pointcut>
    <aop:advisor advice-ref="myAdvice" pointcut-ref="myPt"></aop:advisor>
</aop:config>
           

注解模式:

1. 開啟注解

<tx:annotation-driven></tx:annotation-driven>
           

2. 在對應的類上面加上注解,則該類的所有方法都會采取事務管理。隻對某個方法進行事務管理,在放發明上面加上注解,兩個地方都有,則以方法上面的為準

@Transactional(isolation = Isolation.DEFAULT,readOnly = false,propagation = Propagation.REQUIRED)
           

我所了解的隻有這麼多,希望你們不要介意,如果覺得哪裡有不對的,希望指出,加以修改。